package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushSetEntity;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.data.service.CabinetFileService;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.AddMuchFieldPojo;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.AddBatchDTO;
import com.xbongbong.paas.pojo.dto.AggSumDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.pojo.dto.PaymentTaskDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.AggSumVO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.RangeScreenConstant;
import com.xbongbong.pro.detailtab.dto.LinkAddBeforeDTO;
import com.xbongbong.pro.detailtab.vo.DetailTabLinkAddBeforeVO;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.CommunicatePlanNotifyTypeEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PaymentTaskNotifyTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ApprovalErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessRuleErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CommuicatePlanErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ContractErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ImportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PayPlanErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PaymentErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.message.constant.PaymentTaskPushConstant;
import com.xbongbong.pro.message.enums.PushObjectTypeEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.message.model.PushSetModel;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.pushset.PaymentTaskPushSet;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.pro.payment.pojo.vo.PaymentUpdateBatchMuchFieldVO;
import com.xbongbong.pro.paymenttask.pojo.PaymentTaskPlanPojo;
import com.xbongbong.pro.paymenttask.pojo.dto.PaymentTaskDTO;
import com.xbongbong.pro.paymenttask.pojo.dto.PaymentTaskDeleteBatchDTO;
import com.xbongbong.pro.paymenttask.pojo.dto.PaymentTaskGetDTO;
import com.xbongbong.pro.paymenttask.pojo.dto.PaymentTaskInsertBatchDTO;
import com.xbongbong.pro.paymenttask.pojo.dto.PaymentTaskUpdateBatchMuchFieldDTO;
import com.xbongbong.pro.paymenttask.pojo.vo.PaymentTaskDeleteBatchVO;
import com.xbongbong.pro.paymenttask.pojo.vo.PaymentTaskInsertBatchVO;
import com.xbongbong.pro.paymenttask.pojo.vo.PaymentTaskPlanDayListVO;
import com.xbongbong.pro.paymenttask.pojo.vo.PaymentTaskPlanVO;
import com.xbongbong.pro.paymenttask.pojo.vo.PaymentTaskStatisicsListVO;
import com.xbongbong.pro.paymenttask.pojo.vo.PaymentTaskStatisicsVO;
import com.xbongbong.pro.paymenttask.pojo.vo.PaymentTaskVO;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.service.toolbox.elasticsearch.help.ProEsHelper;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.pro.weblist.pojo.SpecialListFieldPojo;
import com.xbongbong.pro.weblist.pojo.dto.SaasBaseDTO;
import com.xbongbong.pro.weblist.pojo.vo.SpecialListFilterVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.PageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.fund.PaymentTaskConstant;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.PaymentTaskUserEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentTaskEntityExt;
import com.xbongbong.saas.enums.ExecutorCheckBoxEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.LinkAddOperationFlagEnum;
import com.xbongbong.saas.enums.ListContentButtonEnum;
import com.xbongbong.saas.enums.ListTopButtonEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.PlaceholderEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PaymentTaskEnum;
import com.xbongbong.saas.enums.dictionary.PaymentTaskStatusEnum;
import com.xbongbong.saas.enums.subform.PaymentTaskTeamEnum;
import com.xbongbong.saas.help.BasicHelper;
import com.xbongbong.saas.help.FieldAttrHelp;
import com.xbongbong.saas.help.ReceivablesHelper;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.fund.PaymentTaskHelp;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.PaymentTaskModel;
import com.xbongbong.saas.model.PaymentTaskUserModel;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.PaymentService;
import com.xbongbong.saas.service.PaymentTaskService;
import com.xbongbong.saas.service.PaymentTaskUserService;
import com.xbongbong.saas.service.SaasListService;
import com.xbongbong.saas.service.toolbox.help.FundMoneyHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.join.aggregations.ChildrenAggregationBuilder;
import org.elasticsearch.join.aggregations.JoinAggregationBuilders;
import org.elasticsearch.join.query.HasChildQueryBuilder;
import org.elasticsearch.join.query.JoinQueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.ExtendedBounds;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author: 汪腾伟
 * @date: 2020/7/29
 * @desrcption: 回款计划接口实现层
 * @version:1.0
 */
@Service("paymentTaskService")
public class PaymentTaskServiceImpl implements PaymentTaskService {

    @Resource
    private PaasFormExplainModel paasFormExplainModel;

    @Resource
    private FieldAttrHelp fieldAttrHelp;

    @Resource
    private SaasSaveHelp saasSaveHelp;

    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private UserModel userModel;

    @Resource
    private EsHelper esHelper;

    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;

    @Resource
    private PaymentTaskUserModel paymentTaskUserModel;

    @Resource
    private ReceivablesHelper receivablesHelper;

    @Resource
    private PaasFormModel paasFormModel;

    @Resource
    private FundSetService fundSetService;

    @Resource
    private PaymentTaskModel paymentTaskModel;

    @Resource
    private SaasListService saasListService;

    @Resource
    private PushSetModel pushSetModel;

    @Resource
    private PushHelper pushHelper;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private MessageService messageService;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PushModel pushModel;
    @Resource
    private CabinetFileService cabinetFileService;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private ProEsHelper proEsHelper;
    @Resource
    private PaymentTaskUserService paymentTaskUserService;
    @Resource
    private FundMoneyHelp fundMoneyHelp;
    @Resource
    private ContractModel contractModel;
    @Resource
    private PaymentTaskHelp paymentTaskHelp;
    @Resource
    private PaymentService paymentService;

    private static final String TREE_TYPE_STAFF = "staff";

    private static final String TREE_TYPE_DEPARTMENT = "department";

    private static final String NAME_LIKE = "nameLike";

    private static final Logger LOG = LoggerFactory.getLogger(PaymentTaskServiceImpl.class);

    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private IndexTypeModel indexTypeModel;


    /**
     * 回款计划列表界面需要显示的范围筛选字段
     *
     * @param saasBaseDTO
     * @return
     * @throws XbbException
     */
    @Override
    public SpecialListFilterVO statusSearch(SaasBaseDTO saasBaseDTO) throws XbbException {
        SpecialListFilterVO specialListFilterVO = new SpecialListFilterVO();
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(saasBaseDTO.getFormId(), saasBaseDTO.getCorpid());
        if (Objects.isNull(explainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Integer distributorMark = explainEntity.getDistributorMark();
        //设置范围筛选
        List<SpecialListFieldPojo> fieldList = new ArrayList<>();

        String explains = explainEntity.getExplains();
        //设置执行人筛选字段
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains);
        FieldAttrEntity executorAttrEntity = explainMap.get(PaymentTaskEnum.EXECUTOR.getAttr());
        FieldAttrEntity statusAttrEntity = explainMap.get(PaymentTaskEnum.STATUS.getAttr());
        FieldAttrEntity customerAttrEntity = explainMap.get(PaymentTaskEnum.LINK_CUSTOMER.getAttr());
        List<ItemPoJo> itemPoJoLists = new ArrayList<>();
        ItemPoJo itemPoJo = new ItemPoJo(executorAttrEntity.getAttrName(), executorAttrEntity.getAttr());
        itemPoJoLists.add(itemPoJo);
        SpecialListFieldPojo rangeScreenPojo = new SpecialListFieldPojo(RangeScreenConstant.RANGE_SCREEN, FieldTypeEnum.RANGE_SCREEN.getDescription(),
                FieldTypeEnum.RANGE_SCREEN.getType(), 0, I18nMessageUtil.getMessage(RangeScreenConstant.SELECT), itemPoJoLists);
        fieldList.add(rangeScreenPojo);

        //设置回款计划筛选字段
        List<PaymentTaskStatusEnum> paymentTaskStatusEnums = PaymentTaskStatusEnum.getList();
        StringBuilder valueBuilder = new StringBuilder();
        for (PaymentTaskStatusEnum statusEnum : paymentTaskStatusEnums) {
            StringUtil.stringBuilderAppendSuffix(valueBuilder, ",", statusEnum.getAlias());
        }
        List<ItemPoJo> itemPoJoList = fieldAttrHelp.initItem(valueBuilder.toString());
        SpecialListFieldPojo specialListFieldPojo = new SpecialListFieldPojo(PaymentTaskEnum.STATUS.getSaasAttr(), statusAttrEntity.getAttrName(),
                FieldTypeEnum.COMBO.getType(), 0, I18nMessageUtil.getMessage(I18nStringConstant.SELECT_PLAN_STATUS), itemPoJoList);
        fieldList.add(specialListFieldPojo);

        //设置关联客户筛选字段
        String placeholder = Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode()) ? PlaceholderEnum.DISTRIBUTOR_MANAGEMENT.getName() : I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_NAME_OR_PHONE_SEARCH);
        SpecialListFieldPojo customerPojo = new SpecialListFieldPojo(NAME_LIKE, customerAttrEntity.getAttrName(), FieldTypeEnum.TEXT.getType(), placeholder);
        fieldList.add(customerPojo);
        specialListFilterVO.setFieldList(fieldList);
        return specialListFilterVO;
    }

    /**
     * 保存回款计划之前需要做的一些操作，解析传过来的参数变成可以保存到es中的数据
     *
     * @param validateDataDTO
     */
    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        String corpid = validateDataDTO.getCorpid();
        JSONObject data = validateDataDTO.getData();
        Long id = validateDataDTO.getDataId();
        saasSaveHelp.formatLinkBusiness4Save(data, PaymentTaskEnum.LINK_CUSTOMER.getAttr(), PaymentTaskEnum.LINK_CUSTOMER_HIDE.getAttr(), PaymentTaskEnum.LINK_CUSTOMER.getFieldType());
        saasSaveHelp.formatLinkBusiness4Save(data, PaymentTaskEnum.LINK_CONTRACT.getAttr(), PaymentTaskEnum.LINK_CONTRACT_HIDE.getAttr(), PaymentTaskEnum.LINK_CONTRACT.getFieldType());
        if (id == null || id < 1) {
            // 新建回款计划状态为未完成
            data.put(PaymentTaskEnum.STATUS.getAttr(), PaymentTaskStatusEnum.NO_FINISH.getCode());
        }
        Long communicateTime = FastJsonHelper.getLongFromFormData(data, PaymentTaskEnum.EXECUTOR_TIME.getAttr());
        Integer notifyType = FastJsonHelper.getIntegerOrDefaultFromFormData(data, PaymentTaskEnum.NOTIFY_TYPE.getAttr(), PaymentTaskNotifyTypeEnum.NO_NOTIFY.getCode());
        Long notifyTime = FastJsonHelper.getLongFromFormData(data, PaymentTaskEnum.NOTIFY_TIME.getAttr());
        notifyTime = checkCommunicateTime(communicateTime, notifyType, notifyTime, validateDataDTO.getDataId(), null);
        if (notifyType.equals(PaymentTaskNotifyTypeEnum.NO_NOTIFY.getCode())) {
            notifyTime = null;
        }
        data.put(PaymentTaskEnum.NOTIFY_TIME.getAttr(), notifyTime);
        Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(data, PaymentTaskEnum.LINK_CUSTOMER.getAttr(), 0L);
        //下面是一些判断校验 （1）计划收款金额需要大于0 （2）计划收款金额不能大于合同的可添加金额,这边需要重新再调用一个计算金额的方法
        Long contractId = FastJsonHelper.getLongOrDefaultFromFormData(data, PaymentTaskEnum.LINK_CONTRACT.getAttr(), 0L);
        validateExeCutor(data, contractId, corpid);
        Double planNum  = FastJsonHelper.getDoubleOrDefaultFromFormData(data, PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr(), 0D);
        PaymentTaskGetDTO paymentTaskGetDTO = new PaymentTaskGetDTO();
        paymentTaskGetDTO.setDataId(contractId);
        paymentTaskGetDTO.setCorpid(validateDataDTO.getCorpid());
        PaymentTaskVO paymentTaskAmount = getPaymentTaskAmount(paymentTaskGetDTO);
        if(Objects.isNull(id) && !Objects.isNull(paymentTaskAmount) && !Objects.isNull(paymentTaskAmount.getPaymentTaskMaxMoney())) {
            if(Objects.isNull(planNum) || planNum <= BasicConstant.ZERO_DOUBLE) {
                throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247003);
            }
            if(Objects.nonNull(planNum) && planNum > paymentTaskAmount.getPaymentTaskMaxMoney()) {
                throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247004);
            }
        }
        validateDataDTO.setData(data);
    }


    /**
     * 保存完回款计划之后，需要进行消息推送以及定时消息推送，还需要保存执行人信息
     *
     * @param saasFormSaveDTO
     */
    @Override
    public void afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long id = newPaasFormDataEntity.getId();
        String corpid = newPaasFormDataEntity.getCorpid();
        String userId = saasFormSaveDTO.getUserId();
        JSONObject newData = newPaasFormDataEntity.getData();
        Long newContractId = FastJsonHelper.getLongOrDefaultFromFormData(newData, PaymentTaskEnum.LINK_CONTRACT.getAttr(), 0L);
        List<String> userList = saasSaveHelp.saveExecutor2PaymentTaskUser(newData, PaymentTaskEnum.EXECUTOR.getAttr(), PaymentTaskEnum.EXECUTOR_LINKED_TEXT.getAttr(), newContractId, corpid, id, userId);

        /*
        //手动创建应收，无需和task挂钩
        Long modelType = fundSetService.getModelType(corpid, XbbRefTypeEnum.CRM);
        if (Objects.equals(modelType, ModelTypeEnum.PLAN.getCode()) && saasFormSaveDTO.getIsNew()) {
            PaymentTaskEntityExt paymentTaskEntityExt = new PaymentTaskEntityExt();
            BeanUtil.copyProperties(newPaasFormDataEntity,paymentTaskEntityExt);
            List<PaymentTaskEntityExt> paymentTaskEntityExts = Arrays.asList(paymentTaskEntityExt);
            //新建应收款
            receivablesHelper.createReceivablesHandle(saasFormSaveDTO, modelType, paymentTaskEntityExts);
        }*/
        PaymentTaskEntityExt paymentTaskEntityExt = new PaymentTaskEntityExt();
        BeanUtil.copyProperties(newPaasFormDataEntity,paymentTaskEntityExt);
        paymentTaskEntityExt.setPushUserlist(userList);
        List<PaymentTaskEntityExt> paymentTaskEntityExts = Arrays.asList(paymentTaskEntityExt);
        sendPaymentTaskMessage(paymentTaskEntityExts, saasFormSaveDTO, corpid);
    }

    /**
     *统一一个发送回款计划消息的方法，参考访客计划的消息，单独拎出来，所以没有放在统一的方法中;
     */
    public void sendPaymentTaskMessage(List<PaymentTaskEntityExt> paymentTaskEntityExts, SaasFormSaveDTO saasFormSaveDTO, String corpid) throws XbbException {
        UserVO loginUser = saasFormSaveDTO.getLoginUser();
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(loginUser, userEntity);
        if (saasFormSaveDTO.getIsNew()) {
            if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                for (PaymentTaskEntityExt paymentTaskEntityExt : paymentTaskEntityExts) {
                    List<String> userList = new ArrayList<>();
                    List<String> pushUserlist = paymentTaskEntityExt.getPushUserlist();
                    Long id = paymentTaskEntityExt.getId();
                    if (CollectionsUtil.isNotEmpty(pushUserlist)) {
                        //回款计划新建消息推送
                        PaymentTaskPushSet paymentTaskPushSet = new PaymentTaskPushSet();
                        PushSetEntity pushSetEntity = paymentTaskPushSet.getPushSet(corpid, PushTypeEnum.PAYMENT_TASK_ADD_PUSH.getSubCode(), pushSetModel);
                        if (Objects.equals(pushSetEntity.getEnable(), BasicConstant.ONE)) {
                            String pushObjectString = pushSetEntity.getPushObject();
                            JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectString);
                            String typeString = pushObject.getString("type");
                            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
                            for (Object object : typeJsonArray) {
                                JSONObject jsonObject = (JSONObject) object;
                                Integer enable = jsonObject.getInteger("enable");
                                if (Objects.equals(enable, 1)) {
                                    String alias = jsonObject.getString("alias");
                                    if (Objects.equals(alias, PushObjectTypeEnum.EXECUTOR.getAlias())) {
                                        userList.addAll(pushUserlist);
                                    }
                                }
                            }
                            userList.addAll(pushHelper.getPushUserIdList(userEntity, pushObjectString, userList, DateUtil.getInt()));
                            //去重
                            userList = userList.stream().distinct().collect(Collectors.toList());
                            userList.remove(loginUser.getUserId());
                            PushRefTypePojo.Options options = new PushRefTypePojo.Options(paymentTaskEntityExt.getAppId(), paymentTaskEntityExt.getMenuId(), paymentTaskEntityExt.getFormId(), id, Collections.singletonList(id), SaasMarkEnum.SAAS.getCode(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getSubBusinessType());
                            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, userList, Collections.singletonList(id), 0, null, I18nMessageUtil.getMessage(PaymentTaskPushConstant.PAYMENT_TASK_NEW_TITLE), String.format(I18nMessageUtil.getMessage(PaymentTaskPushConstant.PAYMENT_TASK_NEW_CONTENT), saasFormSaveDTO.getLoginUserName(), paymentTaskEntityExt.getData().getString(PaymentTaskEnum.LINK_CONTRACT_HIDE.getAttr())), null, options);
                            baseProducer.sendMessage(PushTypeEnum.PAYMENT_TASK_ADD_PUSH, messageRabbitMqDTO);
                        }
                    }
                }
            }

            //回款计划提醒保存(新建回款计划时同时保存消息)
            for (PaymentTaskEntityExt paymentTaskEntityExt : paymentTaskEntityExts) {
                List<String> userList = new ArrayList<>();
                Long id = paymentTaskEntityExt.getId();
                List<String> pushPaymentTaskUserlist = paymentTaskEntityExt.getPushUserlist();
                JSONObject newData = paymentTaskEntityExt.getData();
                Long pushTime = newData.getLong(PaymentTaskEnum.NOTIFY_TIME.getAttr());
                if (Objects.isNull(pushTime)) {
                    continue;
                }
                userList.addAll(pushPaymentTaskUserlist);
                PushRefTypePojo.Options optionsRemind = new PushRefTypePojo.Options(paymentTaskEntityExt.getAppId(), paymentTaskEntityExt.getMenuId(), paymentTaskEntityExt.getFormId(), id, Collections.singletonList(id), SaasMarkEnum.SAAS.getCode(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getSubBusinessType());
                MessageRabbitMqDTO messageRabbitMqDTORemind = new MessageRabbitMqDTO(corpid, userList, Collections.singletonList(id), 1, pushTime, paymentTaskEntityExt.getSerialNo(), null, null, optionsRemind);
                messageService.insertPushData(messageRabbitMqDTORemind, PushTypeEnum.PAYMENT_TASK_PUSH);
            }

        }


    }

    /**
     * 获取回款计划金额信息 总公式: 合同可添加金额 = 合同金额 - [（核销预收款金额 - 红冲核销预收款金额） - （已核销金额 - 红冲已核销金额） - 已坏账金额 - 未完成回款计划金额]
     * 红冲核销预收款、红冲已核销存储的时候都是负数
     *
     * @param paymentTaskGetDTO
     * @return
     */
    @Override
    public PaymentTaskVO getPaymentTaskAmount(PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        long contractId = paymentTaskGetDTO.getDataId();
        String corpid = paymentTaskGetDTO.getCorpid();
        FormDataUpdateGetDTO formDataUpdateGetDTO = new FormDataUpdateGetDTO();
        formDataUpdateGetDTO.setCorpid(corpid);
        formDataUpdateGetDTO.setDataId(contractId);
        //根据合同id查询除合同信息
        ContractEntityExt contractEntityExt = contractModel.getByKey(contractId, corpid);
        JSONObject data = contractEntityExt.getData();
        double contractMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(data, ContractEnum.AMOUNT.getAttr(), 0D);
        //其实是核销的与红冲的一起计算，但是为了直接调用别人方法，这边（1）核销预收款、核销一起计算  （2）红冲核销预收、红冲核销一起计算
        //核销预收款、核销总计
        Double  totalSheetWriteOffAmount = fundMoneyHelp.getSheetTotalWriteOffAmount(XbbRefTypeEnum.PAYMENT_SHEET, formDataUpdateGetDTO, true, true, PaymentSheetEnum.CONTRACT.getAttr());
        //红冲核销预收、红冲核销、坏账总计
        Double  totalSheetRedAndBadAmount = fundMoneyHelp.getSheetRedAndBadAmount(XbbRefTypeEnum.PAYMENT_SHEET,formDataUpdateGetDTO,true,true,PaymentSheetEnum.CONTRACT.getAttr());
        //查询回款计划的相关金额
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.LINK_CONTRACT), contractId));
        boolQueryBuilder.filter(termQuery(PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.STATUS), PaymentTaskStatusEnum.NO_FINISH.getCode()));
        List<String> sumFieldList = Arrays.asList(PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.PAYMENT_TASK_NUM));
        JSONObject jsonObject = esHelper.sumMuchField4Some(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK, boolQueryBuilder, sumFieldList);
        //未收的回款计划总金额
        double paymentTaskAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.PAYMENT_TASK_NUM), 0d);
        //合同金额 - 回款单相关 - 回款计划未完成相关
        double canAddmoney = Arith.sub(Arith.sub(Arith.sub(contractMoney, totalSheetWriteOffAmount), totalSheetRedAndBadAmount), paymentTaskAmount);
        //开始返回封装数据，并且要根据回款计划表单解释中的关于计划收款金额的精度返回
        PaymentTaskVO paymentTaskVO = new PaymentTaskVO();
        if (canAddmoney <= BasicConstant.ZERO_DOUBLE) {
            canAddmoney = BasicConstant.ZERO_DOUBLE;
        }
        paymentTaskVO.setPaymentTaskMaxMoney(canAddmoney);
        return paymentTaskVO;
    }



    /**
     * 获取回款计划列表信息
     *
     * @param paymentTaskGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public PaymentTaskPlanVO listPaymentTask(PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        paymentTaskGetDTO.setOperateType(PaymentTaskConstant.PAYMENT_TASK_LIST);
        List<ConditionsEntityExt> conditionsEntityExtList = setConditionList(paymentTaskGetDTO);
        // 父子文档查询参数
        Set<String> userSet = setTeamCondition(paymentTaskGetDTO, conditionsEntityExtList);
        List<ConditionsEntityExt> dateCondition = getReturnDateCondition(paymentTaskGetDTO);
        conditionsEntityExtList.addAll(dateCondition);
        //处理需要返回es的字段
//        handleFieldList(paymentTaskGetDTO);
        XbbAggregatedPage<PaasFormDataEntityExt> result = esList(paymentTaskGetDTO, conditionsEntityExtList, paymentTaskGetDTO.getPage(), paymentTaskGetDTO.getPageSize());
        List<PaasFormDataEntityExt> list = result.getContent();
        userSet.add(paymentTaskGetDTO.getUserId());
        Set<String> creatorUserSet = new HashSet<>();
        for (PaasFormDataEntityExt entity : list) {
            // 系统生成的不查询
            if (!Objects.equals(PaasConstant.SYS_USER_ID, entity.getCreatorId())) {
                creatorUserSet.add(entity.getCreatorId());
            }
        }
        Map<String, String> userNameMap = userModel.getUserNameMap(paymentTaskGetDTO.getCorpid(), new ArrayList<>(creatorUserSet));
        //封装返回格式
        PaymentTaskPlanVO paymentTaskPlanVO = getReturnPaymentTaskList(paymentTaskGetDTO, list, userNameMap);
        return paymentTaskPlanVO;
    }

    /**
     * 封装一个es中需要返回的字段列表
     *
     * @param paymentTaskGetDTO
     * @throws XbbException
     */
    private void handleFieldList(PaymentTaskGetDTO paymentTaskGetDTO)throws XbbException{
        Integer distributorMark = paymentTaskGetDTO.getDistributorMark();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.PAYMENT_TASK.getCode(), paymentTaskGetDTO.getCorpid(), distributorMark);
        if (Objects.isNull(paasFormExplainEntity)) {
            LOG.error("communicatePlan list error:corpid:" + paymentTaskGetDTO.getCorpid() + ",user:" + paymentTaskGetDTO.getLoginUserName() + ",userId:" + paymentTaskGetDTO.getUserId());
            throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        List<String> fieldList = new ArrayList<>();
        explainList.forEach((item) -> {
            if (Objects.equals(item.getIsOpen(), 1) || Objects.equals(item.getIsRedundant(), 1)) {
                fieldList.add(item.getAttr());
            }
        });
        paymentTaskGetDTO.setFieldList(fieldList);
    }

    /**
     * 获取回款计划具体的内容
     *
     * @param list
     * @param userNameMap
     * @return
     */
    private PaymentTaskPlanVO getReturnPaymentTaskList(PaymentTaskGetDTO paymentTaskGetDTO, List<PaasFormDataEntityExt> list, Map<String, String> userNameMap) {
        List<PaymentTaskPlanPojo> paymentTaskPlanPojos = new ArrayList<>();
        PaymentTaskPlanVO paymentTaskPlanVO = new PaymentTaskPlanVO();
        List<Long> planIdList = new ArrayList<>();
        for (PaasFormDataEntityExt paasFormDataEntityExt : list) {
            planIdList.add(paasFormDataEntityExt.getDataId());
            JSONObject data = paasFormDataEntityExt.getData();
            PaymentTaskPlanPojo paymentTaskPlanPojo = new PaymentTaskPlanPojo();
            paymentTaskPlanPojo.setId(paasFormDataEntityExt.getDataId());
            paymentTaskPlanPojo.setSerialNo(paasFormDataEntityExt.getSerialNo());
            paymentTaskPlanPojo.setCommunicateTime(data.getLong(PaymentTaskEnum.EXECUTOR_TIME.getAttr()));
            paymentTaskPlanPojo.setCustomerId(data.getLong(PaymentTaskEnum.LINK_CUSTOMER.getAttr()));
            paymentTaskPlanPojo.setPaymentTaskNum(data.getDouble(PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr()));
            paymentTaskPlanPojo.setCustomerName(data.getString(PaymentTaskEnum.LINK_CUSTOMER_HIDE.getAttr()));
            paymentTaskPlanPojo.setName(paasFormDataEntityExt.getSerialNo());
            paymentTaskPlanPojo.setIsFinish(data.getInteger(PaymentTaskEnum.STATUS.getAttr()));
            if (Objects.equals(PaasConstant.SYS_USER_ID, paasFormDataEntityExt.getCreatorId())) {
                paymentTaskPlanPojo.setUserId(paasFormDataEntityExt.getCreatorId());
                paymentTaskPlanPojo.setUserName(I18nMessageUtil.getMessage(PaasConstant.SYS_GENERATED));
            }else {
                paymentTaskPlanPojo.setUserId(paasFormDataEntityExt.getCreatorId());
                paymentTaskPlanPojo.setUserName(userNameMap.get(paasFormDataEntityExt.getCreatorId()));
            }
            //与回款计划相关的相关信息，便于跳转
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("dataId", paasFormDataEntityExt.getDataId());
            jsonObject.put("saasMark", SaasMarkEnum.SAAS.getCode());
            jsonObject.put("businessType", XbbRefTypeEnum.PAYMENT_TASK.getCode());
            jsonObject.put("appId", paasFormDataEntityExt.getAppId());
            jsonObject.put("menuId", paasFormDataEntityExt.getMenuId());
            jsonObject.put("formId", paasFormDataEntityExt.getFormId());
            //与客户相关，便于跳转
            JSONObject linkCustomer = new JSONObject();
            linkCustomer.put(StringConstant.DATA_ID, data.getLong(PaymentTaskEnum.LINK_CUSTOMER.getAttr()));
            linkCustomer.put("saasMark", SaasMarkEnum.SAAS.getCode());
            linkCustomer.put(StringConstant.BUSINESS_TYPE, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            //返回实体
            paymentTaskPlanPojo.setLinkCustomer(linkCustomer);
            paymentTaskPlanPojo.setSimpleEntity(jsonObject);
            paymentTaskPlanPojos.add(paymentTaskPlanPojo);
        }
        paymentTaskPlanVO.setPlanList(paymentTaskPlanPojos);

        //封装分页信息
        long num = list.size();
        PageHelper pageHelper = new PageHelper(paymentTaskGetDTO.getPage(), paymentTaskGetDTO.getPageSize());
        pageHelper.setRowsCount((int) num);
        paymentTaskPlanVO.setPageHelper(pageHelper);

        //封装按钮信息
        PaymentTaskPlanVO paymentTaskPlanButtonVo = getReturnPaymentTaskButton(paymentTaskGetDTO);
        paymentTaskPlanVO.setTopPermissions(ObjectUtils.isEmpty(paymentTaskPlanButtonVo) ? null : paymentTaskPlanButtonVo.getTopPermissions());
        paymentTaskPlanVO.setContentPermissions(ObjectUtils.isEmpty(paymentTaskPlanButtonVo) ? null : paymentTaskPlanButtonVo.getContentPermissions());

        //封装用户信息
        PaymentTaskPlanVO paymentTaskPlanUserVo = getReturnPaymentTaskUser(planIdList,paymentTaskGetDTO);
        paymentTaskPlanVO.setUserMap(ObjectUtils.isEmpty(paymentTaskPlanUserVo) ? null : paymentTaskPlanUserVo.getUserMap());
        return paymentTaskPlanVO;
    }

    /**
     * 进行回款计划列表右上角按钮返回
     *
     * @param paymentTaskGetDTO
     * @return
     */
    private PaymentTaskPlanVO getReturnPaymentTaskButton(PaymentTaskGetDTO paymentTaskGetDTO){
        List<ListTopButtonEnum> topButtonEnumList = ListTopButtonEnum.getByBusinessType(XbbRefTypeEnum.PAYMENT_TASK.getCode());
        List<ButtonPojo> topButtonList = new ArrayList<>();
        UserVO userVO = paymentTaskGetDTO.getLoginUser();
        for (ListTopButtonEnum topButtonEnum : topButtonEnumList){
            if (Objects.equals(topButtonEnum, ListTopButtonEnum.PAYMENT_TASK_ADD) && !userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_TASK_ADD.getAlias())) {
                continue;
            } else if (Objects.equals(topButtonEnum, ListTopButtonEnum.PAYMENT_TASK_EXPORT) && !userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_TASK_EXPORT.getAlias())) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(topButtonEnum.getAnEnum(),buttonPojo);
            buttonPojo.setDistributorMark(paymentTaskGetDTO.getDistributorMark());
            topButtonList.add(buttonPojo);
        }
        //列表内容里面的具体按钮显示
        List<ListContentButtonEnum> contentButtonEnumList = ListContentButtonEnum.getByBusinessType(XbbRefTypeEnum.PAYMENT_TASK.getCode());
        List<ButtonPojo> contentButtonList = new ArrayList<>();
        for (ListContentButtonEnum contentButtonEnum : contentButtonEnumList){
            if (Objects.equals(contentButtonEnum, ListContentButtonEnum.PAYMENT_TASK_DEL) && !userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_TASK_DELETE.getAlias())) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(contentButtonEnum.getAnEnum(),buttonPojo);
            buttonPojo.setDistributorMark(paymentTaskGetDTO.getDistributorMark());
            contentButtonList.add(buttonPojo);
        }
        PaymentTaskPlanVO paymentTaskPlanVO = new PaymentTaskPlanVO();
        paymentTaskPlanVO.setTopPermissions(topButtonList);
        paymentTaskPlanVO.setContentPermissions(contentButtonList);
        return paymentTaskPlanVO;
    }


    /**
     * 获取回款计划和回款计划执行人的对应关系
     *
     * @param planIdList
     * @param paymentTaskGetDTO
     * @return
     */
    private PaymentTaskPlanVO getReturnPaymentTaskUser(List<Long> planIdList, PaymentTaskGetDTO paymentTaskGetDTO){
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",paymentTaskGetDTO.getCorpid());
        map.put("planIdIn",planIdList);
        map.put("del",0);
        List<PaymentTaskUserEntity> paymentTaskUserEntities = planIdList.isEmpty() ? new ArrayList<>() : paymentTaskUserModel.findEntitys(map);
        Map<String,List<PaymentTaskUserEntity>> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaymentTaskUserEntity entity : paymentTaskUserEntities){
            List<PaymentTaskUserEntity> entityList = userMap.getOrDefault(entity.getDataId().toString(),new ArrayList<>());
            entityList.add(entity);
            userMap.put(entity.getDataId().toString(),entityList);
        }
        PaymentTaskPlanVO paymentTaskPlanVO = new PaymentTaskPlanVO();
        paymentTaskPlanVO.setUserMap(userMap);
        return paymentTaskPlanVO;
    }

    /**
     * es查询
     *
     * @param paymentTaskGetDTO       公司id
     * @param conditionsEntityExtList 查询条件0
     * @return 回款计划数据
     * @throws XbbException
     */
    private XbbAggregatedPage<PaasFormDataEntityExt> esList(PaymentTaskGetDTO paymentTaskGetDTO, List<ConditionsEntityExt> conditionsEntityExtList, Integer page, Integer size) throws XbbException {
        String corpid = paymentTaskGetDTO.getCorpid();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        EsUtil.parseCondition(boolQueryBuilder, conditionsEntityExtList, null, corpid, XbbRefTypeEnum.PAYMENT_TASK.getCode());
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_PAYMENT_TASK.getType()));
        sourceBuilder.sort(new FieldSortBuilder("data." + PaymentTaskEnum.EXECUTOR_TIME.getAttr()).order(SortOrder.ASC));
        sourceBuilder.query(boolQueryBuilder);
        EsUtil.setFieldList(sourceBuilder, paymentTaskGetDTO.getFieldList());
        PageRequest pageRequest;
        try {
            pageRequest = EsUtil.setPage(sourceBuilder, page, size);
        } catch (Exception e) {
            LOG.error("paymentTask error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            LOG.error("paymentTask error", JSONObject.toJSONString(searchRequest));
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return esEntities;
    }

    /**
     * 设置查询条件
     *
     * @param paymentTaskGetDTO 参数
     * @return 查询条件
     */
    @Override
    public List<ConditionsEntityExt> setConditionList(PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        List<ConditionsEntityExt> conditionsEntityExtList = new ArrayList<>();
        rangeScreen(paymentTaskGetDTO, conditionsEntityExtList);
        //回款计划模糊查询，查的是客户名称或电话
        String nameLike = paymentTaskGetDTO.getNameLike();
        List<Object> customerId = new ArrayList<>();
        if (nameLike != null && !StringUtil.isEmpty(nameLike, true)) {
            BoolQueryBuilder nameLikeQuery = boolQuery();
            nameLikeQuery.filter(termQuery("corpid.keyword", paymentTaskGetDTO.getCorpid()));
            nameLikeQuery.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            EsUtil.setNameLike(SaasMarkEnum.SAAS.getCode(), nameLike, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), false, nameLikeQuery, true, null,null);
            IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(paymentTaskGetDTO.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
            List<PaasFormDataEntityExt> customerList = esHelper.findByScroll(indexTypeEnum, nameLikeQuery, PaasFormDataEntityExt.class, Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
            customerList.forEach(item -> {
                customerId.add(item.getDataId());
            });
            if (!customerId.isEmpty()) {
                conditionsEntityExtList.add(EsUtil.packageContions(PaymentTaskEnum.LINK_CUSTOMER.getAttr(), customerId, ConditionEnum.IN, PaymentTaskEnum.LINK_CUSTOMER.getFieldType()));
            } else {
                conditionsEntityExtList.add(EsUtil.packageContions(PaymentTaskEnum.LINK_CUSTOMER.getAttr(), Collections.singletonList(-1L), ConditionEnum.EQUAL, PaymentTaskEnum.LINK_CUSTOMER.getFieldType()));
            }
        }
        //操作类型，1:回款计划列表查询 2:合同订单去查询关联的回款信息 3:回款计划列表日历查询
        if (PaymentTaskConstant.PAYMENT_TASK_ADD == paymentTaskGetDTO.getOperateType()) {
            //属于第二种情况
            ConditionsEntityExt contractCondition = new ConditionsEntityExt();
            contractCondition.setAttr(PaymentTaskEnum.LINK_CONTRACT.getAttr());
            contractCondition.setFieldType(PaymentTaskEnum.LINK_CONTRACT.getFieldType());
            contractCondition.setName(PaymentTaskEnum.LINK_CONTRACT.getAttrName());
            contractCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
            contractCondition.setValue(Collections.singletonList(paymentTaskGetDTO.getDataId()));
            conditionsEntityExtList.add(contractCondition);
        }
        if (PaymentTaskConstant.PAYMENT_DAY_LIST_SEARCH == paymentTaskGetDTO.getOperateType()) {
            //属于第三种情况
            ConditionsEntityExt dateCondition = new ConditionsEntityExt();
            dateCondition.setAttr(PaymentTaskEnum.EXECUTOR_TIME.getAttr());
            dateCondition.setFieldType(PaymentTaskEnum.EXECUTOR_TIME.getFieldType());
            dateCondition.setName(PaymentTaskEnum.EXECUTOR_TIME.getAttrName());
            dateCondition.setSymbol(ConditionEnum.RANGE.getSymbol());
            Long startTime = paymentTaskGetDTO.getStartTime();
            Long endTime = paymentTaskGetDTO.getEndTime();
            dateCondition.setValue(Arrays.asList(startTime,endTime));
            conditionsEntityExtList.add(dateCondition);
        }
        if (PaymentTaskConstant.PAYMENT_TASK_THROUGH == paymentTaskGetDTO.getOperateType()) {
            conditionsEntityExtList.addAll(paymentTaskGetDTO.getConditions());
            conditionsEntityExtList.add(EsUtil.packageContions(PaymentTaskEnum.STATUS.getAttr(), Arrays.asList(PaymentTaskStatusEnum.NO_FINISH.getCode()), ConditionEnum.IN, PaymentTaskEnum.STATUS.getFieldType()));
        }
        if (Objects.nonNull(paymentTaskGetDTO.getPlanDateArr())) {
            conditionsEntityExtList.add(EsUtil.packageContions(
                    CommunicatePlanEnum.COMMUNICATE_TIME.getAttr(), BasicHelper.timeStrToValueList(paymentTaskGetDTO.getPlanDateArr()),
                    ConditionEnum.RANGE, CommunicatePlanEnum.COMMUNICATE_TIME.getFieldType()));
        }
        //formId条件
        Long formId = paymentTaskGetDTO.getFormId();
        ConditionsEntityExt formIdCondition = new ConditionsEntityExt();
        formIdCondition.setAttr(StringConstant.FORM_ID);
        formIdCondition.setFieldType(FieldTypeEnum.DATAID.getType());
        formIdCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
        formIdCondition.setValue(Collections.singletonList((formId)));
        conditionsEntityExtList.add(formIdCondition);

        //回款计划状态
        PaymentTaskStatusEnum statusEnum = PaymentTaskStatusEnum.getByCode(Objects.toString(paymentTaskGetDTO.getStatus(), ""));
        if (statusEnum.equals(PaymentTaskStatusEnum.UNKNOW)) {
            return conditionsEntityExtList;
        }
        ConditionsEntityExt statusCondition = new ConditionsEntityExt();
        statusCondition.setAttr(PaymentTaskEnum.STATUS.getAttr());
        statusCondition.setFieldType(PaymentTaskEnum.STATUS.getFieldType());
        statusCondition.setName(PaymentTaskEnum.STATUS.getAttrName());
        statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
        statusCondition.setValue(Collections.singletonList((statusEnum.getCode().toString())));
        conditionsEntityExtList.add(statusCondition);
        return conditionsEntityExtList;
    }

    /**
     * 获取有回款计划的日期
     *
     * @param paymentTaskGetDTO
     * @return
     */
    @Override
    public PaymentTaskPlanDayListVO dayList(PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException{
        paymentTaskGetDTO.setOperateType(PaymentTaskConstant.PAYMENT_DAY_LIST_SEARCH);
        Long dateInt;
        try {
            String date = paymentTaskGetDTO.getDate();
            dateInt = StringUtil.isEmpty(date) ? DateTimeUtil.getTodayInt() : DateTimeUtil.getInt(date, DateTimeUtil.SDFDate);
        }catch (Exception e){
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214006);
        }
        Long startTime = DateTimeUtil.getFirstDateOfMonthInSomeday(dateInt);
        Long endTime = DateTimeUtil.getLastDateOfMonthInSomeday(dateInt);
        paymentTaskGetDTO.setStartTime(startTime);
        paymentTaskGetDTO.setEndTime(endTime);
        List<ConditionsEntityExt> conditionsEntityExtList = setConditionList(paymentTaskGetDTO);
        JSONObject result = esDayList(conditionsEntityExtList,paymentTaskGetDTO);
        Set<String> dayList = analysisDayList(result);
        PaymentTaskPlanDayListVO paymentTaskPlanDayListVO = new PaymentTaskPlanDayListVO();
        paymentTaskPlanDayListVO.setHasPlanDayArray(dayList);
        return paymentTaskPlanDayListVO;
    }

    /**
     * 统计回款计划
     *
     * @param paymentTaskGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public PaymentTaskStatisicsListVO statistics(PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        paymentTaskGetDTO.setOperateType(PaymentTaskConstant.PAYMENT_TASK_LIST);
        List<ConditionsEntityExt> conditionsEntityExtList = setConditionList(paymentTaskGetDTO);
        List<ConditionsEntityExt> dateCondition = getReturnDateCondition(paymentTaskGetDTO);
        conditionsEntityExtList.addAll(dateCondition);
        JSONObject result = esStatisticsList(conditionsEntityExtList,paymentTaskGetDTO);
        Set<String> userIdSet = analysisStaticsList(result);
        PaymentTaskStatisicsListVO paymentTaskStatisicsListVO = new PaymentTaskStatisicsListVO();

        //手动分页
        Integer page = paymentTaskGetDTO.getPage() == null ? 1 : paymentTaskGetDTO.getPage();
        //日期统计默认分页大小是5
        int statisticsPageSize = PageConstant.DEFAULT_PAGE_SIZE_SMALLER;
        PageHelper pageHelper = new PageHelper(page, statisticsPageSize);
        pageHelper.setRowsCount(userIdSet.size());
        paymentTaskStatisicsListVO.setPageHelper(pageHelper);

        //数据权限判断
        UserEntity userEntity = userModel.getByKey(paymentTaskGetDTO.getUserId(),paymentTaskGetDTO.getCorpid());
        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.PAYMENT_TASK.getCode(), null);
        paymentTaskStatisicsListVO.setDataPermission(Objects.equals(dataPermission,1) ? 0 : 1);
        if (CollectionsUtil.isEmpty(userIdSet)) {
            paymentTaskStatisicsListVO.setStatisticsArray(new ArrayList<>());
            return paymentTaskStatisicsListVO;
        }

        //根据userIdList去查询出planId
        List<String> userIdList = new ArrayList<>();
        userIdList.addAll(userIdSet);
        List<String> subUserList = new ArrayList<>();
        int endPosition = page * statisticsPageSize;
        if (endPosition > userIdList.size()) {
            subUserList = userIdList.subList((page - 1) * statisticsPageSize, userIdList.size());
        } else {
            subUserList = userIdList.subList((page - 1) * statisticsPageSize, page * statisticsPageSize);
        }
        //到es中查询出总共有哪些planIdList
        paymentTaskGetDTO.setUserIdList(subUserList);
        paymentTaskGetDTO.setConditionAnalyse(PaymentTaskConstant.YES_CONDITION_ANALYSE);
        List<ConditionsEntityExt> conditionsEntityExtListSen = setConditionList(paymentTaskGetDTO);
        conditionsEntityExtListSen.addAll(dateCondition);
        BoolQueryBuilder boolQueryBuilder = getReturnBoolQueryBuilder(conditionsEntityExtListSen,paymentTaskGetDTO);
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_PAYMENT_TASK.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        PageRequest pageRequest;
        try {
            pageRequest = EsUtil.setPage(sourceBuilder, 0, 10000);
        } catch (Exception e) {
            LOG.error("paymentTask error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, PaasFormDataEntityExt.class);
        List<Long> planIdList = new ArrayList<>();
        //planId与回款计划的对应关系
        Map<Long, PaasFormDataEntityExt> planIdPlanMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt paasFormDataEntityExt : esEntities.getContent()) {
            planIdList.add(paasFormDataEntityExt.getId());
            planIdPlanMap.put(paasFormDataEntityExt.getId(),paasFormDataEntityExt);
        }
        //查询出userId与planId的对应关系
        List<PaymentTaskUserEntity> userList = paymentTaskUserModel.getUserList(planIdList);
        Map<String,List<PaymentTaskUserEntity>> stringListMap = userList.stream().collect(Collectors.groupingBy(PaymentTaskUserEntity::getUserId));
        //1、userId->planId->paasFormDataEntityExtMap  2、计划个数、完成个数、未完成个数、未完成金额、已完成金额
        List<PaymentTaskStatisicsVO> paymentTaskStatisicsVOS = new ArrayList<>();
        for (String userId : subUserList) {
            int planNum = 0;
            int finishNum = 0;
            int unFinishNum = 0;
            double unFinishMoney = 0d;
            double finishMoney = 0d;
            String userName = "";
            List<PaymentTaskUserEntity> paymentTaskUserEntities= stringListMap.get(userId);
            if (CollectionsUtil.isEmpty(paymentTaskUserEntities)) {
                continue;
            }
            for (PaymentTaskUserEntity paymentTaskUserEntity : paymentTaskUserEntities) {
                userName = paymentTaskUserEntity.getUserName();
                PaasFormDataEntityExt paasFormDataEntityExt = planIdPlanMap.get(paymentTaskUserEntity.getDataId());
                JSONObject jsonObject = paasFormDataEntityExt.getData();
                String status = FastJsonHelper.getStringOrDefaultFromFormData(jsonObject, PaymentTaskEnum.STATUS.getAttr(), "");
                double planMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject,PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr(),0D);
                if (PaymentTaskStatusEnum.NO_FINISH.getCode().equals(status)) {
                    unFinishNum ++;
                    unFinishMoney = unFinishMoney + planMoney;
                } else {
                    finishNum ++;
                    finishMoney = finishMoney + planMoney;
                }
            }
            planNum = unFinishNum + finishNum;
            PaymentTaskStatisicsVO paymentTaskStatisicsVO = new PaymentTaskStatisicsVO();
            paymentTaskStatisicsVO.setNotFinishPlanCount(unFinishNum);
            paymentTaskStatisicsVO.setFinishPlanCount(finishNum);
            paymentTaskStatisicsVO.setNotFinishMoney(unFinishMoney);
            paymentTaskStatisicsVO.setFinishMoney(finishMoney);
            paymentTaskStatisicsVO.setPlanCount(planNum);
            paymentTaskStatisicsVO.setUserId(userId);
            paymentTaskStatisicsVO.setUserName(userName);
            paymentTaskStatisicsVOS.add(paymentTaskStatisicsVO);
        }
        paymentTaskStatisicsListVO.setPageHelper(pageHelper);
        paymentTaskStatisicsListVO.setStatisticsArray(paymentTaskStatisicsVOS);

        return paymentTaskStatisicsListVO;
    }

    /**
     * 新增的时候需要对回款计划解释的处理
     *
     * @param formatExplainDTO
     */
    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, PaymentTaskEnum.EXECUTOR_TIME.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                saasParticularAttributePoJo = saasParticularAttributePoJo == null ? new SaasParticularAttributePoJo() : saasParticularAttributePoJo;
                saasParticularAttributePoJo.setDateLimit(DateTimeUtil.getTodayInt());
                saasParticularAttributePoJo.setLimitType(false);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            }
        }
    }

    /**
     *
     *
     * @param formatExplainDTO
     */
    @Override
    public void formatUpdateExplain(FormatExplainDTO formatExplainDTO) {
        paymentTaskModel.formatUpdateExplain(formatExplainDTO);
    }

    /**
     * 对一些关联数据的处理
     *
     * @param saasAnalysisDataDTO
     * @param result
     */
    @Override
    public void formatData(SaasAnalysisDataDTO saasAnalysisDataDTO, JSONObject result) throws XbbException {
        paymentTaskModel.formatData(saasAnalysisDataDTO, result);
    }

    /**
     * 删除单个回款计划
     * 条件（1）先判断回款计划下面有没有应收款，如果只有应收款，那么先删除应收款再删除回款计划
     * 条件（2）如果应收款下面有回款单，需要提醒先删除回款单
     * 条件（3）如果回款计划已经跟回款单关联，也不能删除
     * 注意：应收款关不关联回款单看应收款中的实收金额或者坏账金额是不是大于0，如果大于0的话就代表应收款关联了回款单
     *
     * @param paymentTaskDeleteBatchDTO
     * @return
     */
    @Override
    public PaymentTaskDeleteBatchVO deleteBatch(PaymentTaskDeleteBatchDTO paymentTaskDeleteBatchDTO) throws XbbException, InterruptedException {
        PaymentTaskDeleteBatchVO paymentTaskDeleteBatchVO = new PaymentTaskDeleteBatchVO();
        List<Long> dataIdList = paymentTaskDeleteBatchDTO.getDataIdList();
        String corpid = paymentTaskDeleteBatchDTO.getCorpid();
        List<PaasFormDataEntityExt> receivablesEntityExt = null;
        List<Long> errorDataId = new ArrayList<>();
        List<String> errorDataNo = new ArrayList<>();
        Set<String> errorTypeSet = new HashSet<>();
        //一次性查询出所有回款计划的信息
        List<PaymentTaskEntityExt> paymentTaskDataEntityList = paymentTaskModel.getPaymentTaskByIdList(corpid, dataIdList);
        List<String> serialist = new ArrayList<>();
        paymentTaskDataEntityList.forEach(paymentTaskEntityExt ->
        {
            serialist.add(paymentTaskEntityExt.getSerialNo());
        });

        //一次性查询出所有应收款信息
        List<PaasFormDataEntityExt> paasFormDataEntityExts = paymentService.checkCanDelPayment(corpid, ModelTypeEnum.PLAN.getXbbRefTypeEnum(), dataIdList);

        //校验回款计划是否已经与回款单绑定，如果回款计划与回款单绑定了，就不允许删除
        PaasFormDataEsListVO paasFormDataEsPaymentSheetListVO = getPaymentSheetListVO(paymentTaskDeleteBatchDTO);
        if (!ObjectUtils.isEmpty(paasFormDataEsPaymentSheetListVO) && !CollectionsUtil.isEmpty(paasFormDataEsPaymentSheetListVO.getPaasFormDataESList())){
            throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247005, String.format(PayPlanErrorCodeEnum.API_ERROR_247005.getMsg(), XbbRefTypeEnum.PAYMENT_TASK.getName(), XbbRefTypeEnum.PAYMENT_TASK.getName()));
        }

        OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
        if (Objects.equals(1, paymentTaskDeleteBatchDTO.getIsBusinessRule())) {
            operateTypeEnum = OperateTypeEnum.RULE_DELETE;
        }
        try {
            if (!CollectionsUtil.isEmpty(paasFormDataEntityExts)) {
                receivablesEntityExt = receivablesHelper.checkReceivablesWhetherCanDel(paasFormDataEntityExts, corpid, errorDataId, errorDataNo, errorTypeSet);
                if(CollectionsUtil.isEmpty(errorDataId)){
                    receivablesHelper.delReceivablesHandle(receivablesEntityExt,operateTypeEnum,paymentTaskDeleteBatchDTO.getUserId(),paymentTaskDeleteBatchDTO.getLoginUserName(),corpid,paymentTaskDeleteBatchDTO.getHttpHeader());
                }else {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(),I18nMessageUtil.getMessage(ErrorMessageConstant.RECEIVABLES_HAS_PAYMENT_SHEET));
                }
            }
            //直接删除回款计划以及需要推送的回款计划消息、回款计划执行者表中的信息
            paymentTaskModel.deleteBatch(dataIdList,corpid);
            pushModel.deleteByRefIds(dataIdList,corpid);
            paymentTaskUserService.deleteBatch(dataIdList,corpid);
        } catch (XbbException e) {
            //回滚与回款计划相关的es，回款计划、回款计划执行者、应收款、红冲应收款、应收款团队、对账单、对账单团队
            threadPoolBeanConfig.addUpdateDelThreadPool().execute(() -> {
                try{
                    //线程睡眠的目的是为了让数据库能回滚完成
                    Thread.sleep(1000L);
                    updateRollbackPaymentTask(dataIdList, corpid);
                } catch (XbbException | InterruptedException e1) {
                    LOG.error("deletePaymentTask rollback" + e1);
                    // 恢复中断状态
                    Thread.currentThread().interrupt();
                }
            });
            throw e;
        } catch (Exception e) {
            LOG.error("paymentTask deleteBatch error", e);
            //回滚与回款计划相关的es，回款计划、回款计划执行者、应收款、红冲应收款、应收款团队、对账单、对账单团队
            threadPoolBeanConfig.addUpdateDelThreadPool().execute(() -> {
                try{
                    //线程睡眠的目的是为了让数据库能回滚完成
                    Thread.sleep(1000L);
                    updateRollbackPaymentTask(dataIdList, corpid);
                } catch (XbbException | InterruptedException e1) {
                    LOG.error("deletePaymentTask rollback" + e1);
                    // 恢复中断状态
                    Thread.currentThread().interrupt();
                }
            });

            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        //生成删除日志(区分单个删除和批量删除)
        String nameStr = StringUtils.join(serialist, "，");
        if(serialist.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), paymentTaskDeleteBatchDTO.getLoginUserName(), XbbRefTypeEnum.PAYMENT_TASK.getName(), dataIdList.size());
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(PaymentTaskEnum.PAYMENT_TASK_NO.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
//            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, paymentTaskDeleteBatchDTO.getUserId(), paymentTaskDeleteBatchDTO.getLoginUserName(), OperateModuleTypeEnum.PAYMENT_TASK_PUSH_SET, operateTypeEnum, "", "", memo,paymentTaskDeleteBatchDTO.getHttpHeader());
        } else if (Objects.equals(dataIdList.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), paymentTaskDeleteBatchDTO.getLoginUserName(), XbbRefTypeEnum.PAYMENT_TASK.getName(), nameStr);
//            mongoLogHelp.buildLog(corpid, paymentTaskDeleteBatchDTO.getUserId(), paymentTaskDeleteBatchDTO.getLoginUserName(), OperateModuleTypeEnum.PAYMENT_TASK_PUSH_SET, operateTypeEnum, dataIdList.get(0).toString(), nameStr, memo, paymentTaskDeleteBatchDTO.getHttpHeader());
        }
        paymentTaskDeleteBatchVO.setDeleteIds(dataIdList);
        return paymentTaskDeleteBatchVO;
    }

    @Override
    public void updateRollbackPaymentTask(Collection<Long> dataIdList, String corpid) throws XbbException {
        if (Objects.isNull(dataIdList) || dataIdList.isEmpty()) {
            return;
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", dataIdList);
        param.put(StringConstant.CORPID, corpid);
        List<PaymentTaskEntityExt> paymentTaskEntityExts = paymentTaskModel.findEntitys(param);
        if (CollectionUtils.isEmpty(paymentTaskEntityExts)) {
            return;
        }
        for (PaymentTaskEntityExt paymentTaskEntityExt : paymentTaskEntityExts) {
            if (Objects.isNull(paymentTaskEntityExt.getId())) {
                continue;
            }
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(paymentTaskEntityExt, paasFormDataEntity);
            proEsHelper.reductionEsInUpdate(paasFormDataEntity, paymentTaskEntityExt.getId(), corpid, IndexTypeEnum.IDX_SAAS_PAYMENT_TASK);
        }
    }

    /**
     * 获取回款单的相关信息
     *
     * @param paymentTaskDeleteBatchDTO
     * @return
     */
    private PaasFormDataEsListVO getPaymentSheetListVO(PaymentTaskDeleteBatchDTO paymentTaskDeleteBatchDTO) throws XbbException {
        List<Long> dataIdList = paymentTaskDeleteBatchDTO.getDataIdList();
        List<Object> list = new ArrayList<>();
        dataIdList.forEach(dataId -> list.add(dataId));
        paymentTaskDeleteBatchDTO.setBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
        FormDataListDTO formDataListDTO = getFormDataListDTO(paymentTaskDeleteBatchDTO);
        List<ConditionsEntityExt> conditionList = new ArrayList<>();
        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
        conditionsEntityExt.setAttr(PaymentSheetEnum.PAYMENT_TASK.getAttr());
        conditionsEntityExt.setFieldType(PaymentSheetEnum.PAYMENT_TASK.getFieldType());
        conditionsEntityExt.setName(PaymentSheetEnum.PAYMENT_TASK.getAttrName());
        conditionsEntityExt.setSymbol(ConditionEnum.IN.getSymbol());
        conditionsEntityExt.setValue(list);
        conditionList.add(conditionsEntityExt);
        formDataListDTO.setConditions(conditionList);
        formDataListDTO.setPage(PageConstant.DEFAULT_INDEX_PAGE);
        formDataListDTO.setPageSize(PageConstant.DEFAULT_PAGE_SIZE);
        PaasFormDataEsListVO paasFormDataEsListVO = saasListService.paymentSheetList(formDataListDTO);
        return paasFormDataEsListVO;
    }

    @Override
    public List<Long> finishPaymentTask(JSONObject data, String corpid) throws XbbException {
        if (data == null) {
            return null;
        }
        List<Long> taskIdList = JsonHelperUtil.parseArray(data.getString(PaymentSheetEnum.PAYMENT_TASK.getAttr()), Long.class);
        if (CollectionsUtil.isNotEmpty(taskIdList)) {
            PaymentTaskDataDTO paymentTaskDataDTO = new PaymentTaskDataDTO();
            paymentTaskDataDTO.setCorpid(corpid);
            paymentTaskDataDTO.setDataIdList(taskIdList);
            updatePaymentTask(paymentTaskDataDTO);
            return taskIdList;
        }
        return null;
    }

    /**
     * 直接完成回款计划
     *
     * @param linkAddBeforeDTO
     * @return
     */
    @Override
    public DetailTabLinkAddBeforeVO updatePaymentTaskStatus(LinkAddBeforeDTO linkAddBeforeDTO) throws XbbException{
        DetailTabLinkAddBeforeVO detailTabLinkAddBeforeVO = new DetailTabLinkAddBeforeVO();
        List<Long> dataIdList = linkAddBeforeDTO.getDataIdList();
        String corpid = linkAddBeforeDTO.getCorpid();
        PaymentTaskDataDTO paymentTaskDataDTO = new PaymentTaskDataDTO();
        paymentTaskDataDTO.setDataIdList(dataIdList);
        paymentTaskDataDTO.setCorpid(corpid);
        updatePaymentTask(paymentTaskDataDTO);
        return detailTabLinkAddBeforeVO;
    }

    /**
     * 一致性同步，使客户名称修改之后，回款计划中的客户名称也能修改
     *
     * @param corpid 公司id
     * @param dataId 客户id
     * @param name 客户名称
     */
    @Override
    public void dataConsistencyUpdateCustomer(String corpid, Long dataId, String name) {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.LINK_CUSTOMER), dataId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            List<PaymentTaskEntityExt> paymentTaskEntityExtList = paymentTaskModel.findEntitys(param);
            List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
            if (Objects.nonNull(paymentTaskEntityExtList) && !paymentTaskEntityExtList.isEmpty()) {
                for (PaymentTaskEntityExt entityExt : paymentTaskEntityExtList) {
                    JSONObject updateData = new JSONObject();
                    updateData.put(PaymentTaskEnum.LINK_CUSTOMER_HIDE.getAttr(), name);
                    updateDataEntityList.add(ExplainUtil.getUpdateData(entityExt.getDataId(), updateData, corpid));

                }
                if (updateDataEntityList.size() > 0) {
                    paymentTaskModel.batchUpdatePaymentTask(updateDataEntityList, corpid);
                }
            }

        } catch (Exception e) {
            LOG.error("PaymentTaskServiceImpl.dataConsistencyUpdateCustomer 出错，corpid=" + corpid + "  customerId=" + dataId + " customerName=" + name, e);
        }
    }

    /**
     *一致性同步，使合同编号修改之后，回款计划中的合同编号也能修改
     *
     * @param corpid 公司id
     * @param dataId 合同id
     * @param serialNo 合同编号
     */
    @Override
    public void dataConsistencyUpdateContract(String corpid, Long dataId, String serialNo) {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.LINK_CONTRACT), dataId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            List<PaymentTaskEntityExt> paymentTaskEntityExtList = paymentTaskModel.findEntitys(param);
            List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
            if (Objects.nonNull(paymentTaskEntityExtList) && !paymentTaskEntityExtList.isEmpty()) {
                for (PaymentTaskEntityExt entityExt : paymentTaskEntityExtList) {
                    JSONObject updateData = new JSONObject();
                    updateData.put(PaymentTaskEnum.LINK_CONTRACT_HIDE.getAttr(), serialNo);
                    updateDataEntityList.add(ExplainUtil.getUpdateData(entityExt.getDataId(), updateData, corpid));

                }
                if (updateDataEntityList.size() > 0) {
                    paymentTaskModel.batchUpdatePaymentTask(updateDataEntityList, corpid);
                }
            }

        } catch (Exception e) {
            LOG.error("PaymentTaskServiceImpl.dataConsistencyUpdateContract 出错，corpid=" + corpid + "  custractId=" + dataId + " serialNo=" + serialNo, e);
        }
    }

    /**
     * 获取传到相应方法内的参数
     *
     * @param paymentTaskDeleteBatchDTO
     * @return
     */
    private FormDataListDTO getFormDataListDTO(PaymentTaskDeleteBatchDTO paymentTaskDeleteBatchDTO) throws XbbException {
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        Map<String, Object> entity = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        entity.put("corpid",paymentTaskDeleteBatchDTO.getCorpid());
        entity.put("businessType",paymentTaskDeleteBatchDTO.getBusinessType());
        entity.put("del",BasicConstant.ZERO);
        List<PaasFormEntity> paasFormEntities = paasFormModel.findEntity(entity);
        if (CollectionsUtil.isEmpty(paasFormEntities)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        PaasFormEntity paasFormEntity = paasFormEntities.get(0);
        formDataListDTO.setBusinessType(paymentTaskDeleteBatchDTO.getBusinessType());
        formDataListDTO.setAppId(paasFormEntity.getAppId());
        formDataListDTO.setFormId(paasFormEntity.getId());
        formDataListDTO.setCorpid(paymentTaskDeleteBatchDTO.getCorpid());
        formDataListDTO.setPage(PageConstant.DEFAULT_INDEX_PAGE);
        formDataListDTO.setPageSize(PageConstant.DEFAULT_PAGE_SIZE);
        formDataListDTO.setLoginUser(paymentTaskDeleteBatchDTO.getLoginUser());
        formDataListDTO.setUserId(paymentTaskDeleteBatchDTO.getUserId());
        formDataListDTO.setSubBusinessType(paymentTaskDeleteBatchDTO.getBusinessType());
        formDataListDTO.setSaasMark(BasicConstant.ONE);
        formDataListDTO.setPlatform(paymentTaskDeleteBatchDTO.getPlatform());
        return formDataListDTO;
    }

    @Override
    public List<ConditionsEntityExt> getReturnDateCondition(PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        Long dateInt;
        try {
            String date = paymentTaskGetDTO.getDate();
            if (StringUtil.isEmpty(date)) {
                dateInt = DateTimeUtil.getTodayInt();
            } else {
                long time = DateTimeUtil.getInt(date, DateTimeUtil.SDFDate);
                dateInt = DateTimeUtil.getTodayInt(time);
            }
        }catch (Exception e){
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214006);
        }
        //大于等于
        ConditionsEntityExt greaterEqualCondition = new ConditionsEntityExt();
        greaterEqualCondition.setAttr(PaymentTaskEnum.EXECUTOR_TIME.getAttr());
        greaterEqualCondition.setFieldType(PaymentTaskEnum.EXECUTOR_TIME.getFieldType());
        greaterEqualCondition.setName(PaymentTaskEnum.EXECUTOR_TIME.getAttrName());
        greaterEqualCondition.setSymbol(ConditionEnum.GREATEREQUAL.getSymbol());
        greaterEqualCondition.setValue(Arrays.asList(dateInt));
        //小于
        ConditionsEntityExt lessThanCondition = new ConditionsEntityExt();
        lessThanCondition.setAttr(PaymentTaskEnum.EXECUTOR_TIME.getAttr());
        lessThanCondition.setFieldType(PaymentTaskEnum.EXECUTOR_TIME.getFieldType());
        lessThanCondition.setName(PaymentTaskEnum.EXECUTOR_TIME.getAttrName());
        lessThanCondition.setSymbol(ConditionEnum.LESSTHAN.getSymbol());
        lessThanCondition.setValue(Arrays.asList(dateInt + TimeConstant.SECONDS_PER_DAY));
        return Arrays.asList(greaterEqualCondition, lessThanCondition);
    }

    /**
     * 获取回款计划统计信息
     *
     * @param conditionsEntityExtList
     * @param paymentTaskGetDTO
     * @return
     */
    private JSONObject esStatisticsList( List<ConditionsEntityExt> conditionsEntityExtList, PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = getReturnBoolQueryBuilder(conditionsEntityExtList,paymentTaskGetDTO);
        //用户分组
        TermsAggregationBuilder termsAgg = AggregationBuilders.terms("aggs02").field(PaymentTaskTeamEnum.getEsAttr(PaymentTaskTeamEnum.USER_ID));
        ChildrenAggregationBuilder childrenAgg = JoinAggregationBuilders.children("aggs01", IndexTypeEnum.IDX_SAAS_PAYMENT_TASK_TEAM.getType());
        childrenAgg.subAggregation(termsAgg);
        return esHelper.elasticAggs4NoBuckets2Object(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK, boolQueryBuilder, childrenAgg);
    }




    /**
     * 解析es聚合数据
     * @param result 聚合数据
     * @return 有计划的日期
     */
    private Set<String> analysisStaticsList(JSONObject result) {
        Set<String> userList = new HashSet<>();
        JSONArray buckets =  result.getJSONObject("aggregations").getJSONObject("aggs01").getJSONObject("aggs02").getJSONArray("buckets");
        for (Object obj : buckets){
            JSONObject json = (JSONObject) obj;
            if (json.getInteger("doc_count") != null && json.getInteger("doc_count") > 0){
                userList.add(json.getString("key"));
            }
        }
        return userList;
    }

    /**
     * 解析es聚合数据
     * @param result 聚合数据
     * @return 有计划的日期
     */
    private Set<String> analysisDayList(JSONObject result) {
        Set<String> dayList = new HashSet<>();
        JSONArray buckets =  result.getJSONObject("aggregations").getJSONObject("aggs01").getJSONArray("buckets");
        for (Object obj : buckets){
            JSONObject json = (JSONObject) obj;
            if (json.getInteger("doc_count") != null && json.getInteger("doc_count") > 0){
                dayList.add(json.getString("key_as_string"));
            }
        }
        return dayList;
    }

    /**
     * es聚合查询有回款计划的日期
     * @param conditionsEntityExtList 筛选条件
     * @param paymentTaskGetDTO
     * @return 聚合结果
     * @throws XbbException
     */
    private JSONObject esDayList(List<ConditionsEntityExt> conditionsEntityExtList, PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException{
        BoolQueryBuilder boolQueryBuilder = getReturnBoolQueryBuilder(conditionsEntityExtList,paymentTaskGetDTO);
        ValuesSourceAggregationBuilder dateHistogramAggregation = AggregationBuilders.dateHistogram("aggs01").field("data." + PaymentTaskEnum.EXECUTOR_TIME.getAttr());
        dateHistogramAggregation.timeZone(ZoneId.systemDefault());
        dateHistogramAggregation.format("yyyy-MM-dd");
        //设置extendedBounds
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
        String min = DateUtil.getString(paymentTaskGetDTO.getStartTime(), sdfDate);
        //比如2017全年应该是2017-01-01到2017-12-31，如果是2018-01-01会返回13个桶
        String max = DateUtil.getString(paymentTaskGetDTO.getEndTime()-1, sdfDate);
        ExtendedBounds extendedBounds = new ExtendedBounds(min, max);
        ((DateHistogramAggregationBuilder) dateHistogramAggregation).extendedBounds(extendedBounds);
        //设置dateHistogramInterval
        DateHistogramInterval dateHistogramInterval = DateHistogramInterval.DAY;
        ((DateHistogramAggregationBuilder) dateHistogramAggregation).dateHistogramInterval(dateHistogramInterval);
        return esHelper.elasticAggs4NoBuckets2Object(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK, boolQueryBuilder, dateHistogramAggregation);
    }

    /**
     * 抽取出查询的es的queryBuilder
     *
     * @param conditionsEntityExtList
     * @param paymentTaskGetDTO
     * @return
     */
    private BoolQueryBuilder getReturnBoolQueryBuilder(List<ConditionsEntityExt> conditionsEntityExtList, PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        EsUtil.parseCondition(boolQueryBuilder,conditionsEntityExtList,null,paymentTaskGetDTO.getCorpid(),XbbRefTypeEnum.PAYMENT_TASK.getCode());
        // 自行拼接父子文档查询参数
        List<String> userIdList = paymentTaskGetDTO.getUserIdList();
        if (CollectionsUtil.isEmpty(userIdList)) {
            userIdList = getUserIdList(paymentTaskGetDTO);
        }
        Set<String> userSet = new LinkedHashSet<>(userIdList);
        String attr = PaymentTaskTeamEnum.getEsAttr(PaymentTaskTeamEnum.USER_ID);
        BoolQueryBuilder teamQueryBuilder = boolQuery();
        teamQueryBuilder.filter(termQuery("corpid.keyword", paymentTaskGetDTO.getCorpid()));
        teamQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        teamQueryBuilder.filter(termsQuery(attr, new ArrayList<>(userSet)));
        HasChildQueryBuilder hasChildQueryBuilder = JoinQueryBuilders.hasChildQuery(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK_TEAM.getType(), teamQueryBuilder, ScoreMode.Max);
        boolQueryBuilder.filter(hasChildQueryBuilder);
        boolQueryBuilder.filter(termQuery("corpid.keyword",paymentTaskGetDTO.getCorpid() ));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel() ));
        return boolQueryBuilder;
    }

    /**
     * 获取执行人员信息
     *
     * @param paymentTaskGetDTO
     * @param conditionsEntityExtList
     * @return
     * @throws XbbException
     */
    @Override
    public Set<String> setTeamCondition(PaymentTaskGetDTO paymentTaskGetDTO, List<ConditionsEntityExt> conditionsEntityExtList) throws XbbException {
        // 获取查询的员工
        List<String> userIdList = getUserIdList(paymentTaskGetDTO);
        Set<String> userSet = new LinkedHashSet<>(userIdList);
        ConditionsEntityExt teamConditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.TEAM_USER.getAlias(), null, FieldTypeEnum.TEAM_USER.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(userSet));
        conditionsEntityExtList.add(teamConditionsEntityExt);
        return userSet;
    }

    /**
     * 返回适合APP展示的回款计划列表信息
     *
     * @param paymentTaskGetDTO
     * @param esEntities
     * @param totalCount
     * @return
     */
    @Override
    public ListAppVO formatPaymentTaskAppList(PaymentTaskGetDTO paymentTaskGetDTO, List<PaasFormDataEntityExt> esEntities, Integer totalCount) throws XbbException {
        List<AppListPojo> appListPojos = new ArrayList<>();
        String statusAttr = PaymentTaskEnum.STATUS.getAttr();
        String status = "";
        Map<Long, String> executorMap = new HashMap<>(esEntities.size() * BasicConstant.TWO);
        List<Long> planIdList = new ArrayList<>();
        planIdList.add(-1L);
        esEntities.forEach(paasFormDataEntityExt -> planIdList.add(paasFormDataEntityExt.getId()));
        Map<String, Object> param = new HashMap<>();
        param.put(StringConstant.CORPID, paymentTaskGetDTO.getCorpid());
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("planIdIn", planIdList);
        List<PaymentTaskUserEntity> entitys = paymentTaskUserModel.findEntitys(param);
        for (PaymentTaskUserEntity entity : entitys) {
            String name = executorMap.get(entity.getDataId());
            if (name == null) {
                executorMap.put(entity.getDataId(), entity.getUserName());
            } else {
                executorMap.put(entity.getDataId(), name + "，" + entity.getUserName());
            }
        }
        for (PaasFormDataEntityExt entity : esEntities) {
            JSONObject data = entity.getData();
            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            for (SummaryDataPoJo summaryDataPoJo : summaryList) {
                if (Objects.equals(summaryDataPoJo.getAttr(), PaymentTaskEnum.EXECUTOR.getAttr())) {
                    summaryDataPoJo.setValue(Arrays.asList(executorMap.get(entity.getId())));
                }
            }
            List<SummaryDataPoJo> lableList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);

            status = FastJsonHelper.getStringOrDefaultFromFormData(data, statusAttr, "");
            PaymentTaskStatusEnum byAlias = PaymentTaskStatusEnum.getByAlias(status);
            if (byAlias != null) {
                status = byAlias.getCode();
            }
            AppListPojo appListPojo = new AppListPojo(entity.getId(), titleList, summaryList, null, lableList, status, entity.getAppId(), entity.getMenuId(), entity.getFormId());
            //dingtalk端需要对金额进行封装
            JSONObject others = handleMoney(data);
            appListPojo.setOthers(others);
            appListPojos.add(appListPojo);

        }
        ListAppVO listAppVO = new ListAppVO();
        listAppVO.setList(appListPojos);
        listAppVO.setTotalCount(totalCount);
        return  listAppVO;
    }

    /**
     * 关联新建回款计划
     *
     * @param handlerExplainInLinkItemDTO
     */
    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        JSONObject linkFormData = handlerExplainInLinkItemDTO.getLinkFormData();
        Long linkDataId = handlerExplainInLinkItemDTO.getLinkDataId();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        PaasFormDataEntityExt paasFormDataEntityExt = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt();
        FieldAttrEntity linkCustomerField = new FieldAttrEntity();
        FieldAttrEntity customerField = new FieldAttrEntity();
        FieldAttrEntity contractField = new FieldAttrEntity();
        for(FieldAttrEntity fieldAttrEntity :explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), PaymentTaskEnum.LINK_CUSTOMER.getAttr())) {
                linkCustomerField = fieldAttrEntity;
            }
        }
        for(FieldAttrEntity fieldAttrEntity :explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), PaymentTaskEnum.LINK_CUSTOMER.getAttr())) {
                customerField = fieldAttrEntity;
            } else if (Objects.equals(fieldAttrEntity.getAttr(), PaymentTaskEnum.LINK_CONTRACT.getAttr())) {
                contractField = fieldAttrEntity;
            }
        }
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(handlerExplainInLinkItemDTO.getLinkBusinessType());
        String customerName = "";
        Double unAmount;
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                customerName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, CustomerManagementEnum.NAME.getAttr(), "");
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, customerName));
                break;
            case CONTRACT:
                unAmount = FastJsonHelper.getDoubleFromFormData(linkFormData, ContractEnum.UN_FINISH_AMOUNT.getAttr());
                if (unAmount == null || unAmount == 0) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.CONTRACT_PAYMENT_SHEET_AMOUNT, I18nMessageUtil.getMessage(CommonConstant.CONTRACT));
                }
                JSONArray contractCustomer = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, ContractEnum.LINK_CUSTOMER.getAttr(), new JSONArray());
                customerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contractCustomer));
                String contractId = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt().getSerialNo();
                contractField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, contractId));
                break;
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
    }

    /**
     *
     * 获取计划收款总额
     *
     * @param corpid 公司id
     * @param dataId 客户id
     * @return
     */
    @Override
    public List<PaasFormDataEntityExt> getPaymentTaskEsDataListByCustomerId(String corpid, Long dataId) throws XbbException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.LINK_CUSTOMER), dataId));
        boolQueryBuilder.filter(termQuery("del", 0));
        boolQueryBuilder.filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_PAYMENT_TASK.getType()));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, PaasConstant.ES_MAX_PAGE_SIZE);
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        return esEntities.getContent();
    }

    /**
     * 更新回款计划
     *
     * @param paymentTaskDataDTO
     * @return
     * @throws XbbException
     */
    @Override
    public void updatePaymentTask(PaymentTaskDataDTO paymentTaskDataDTO) throws XbbException {
        List<Long> dataIdList = paymentTaskDataDTO.getDataIdList();
        String corpid = paymentTaskDataDTO.getCorpid();
        if (CollectionsUtil.isEmpty(dataIdList)) {
            throw new XbbException(BusinessRuleErrorCodeEnum.API_ERROR_261007);
        }
        List<PaymentTaskEntityExt>  paymentTaskEntityExts = paymentTaskModel.getPaymentTaskByIdList(corpid,dataIdList);
        List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
        if(Objects.nonNull(paymentTaskEntityExts)){
            String finishCode = PaymentTaskStatusEnum.FINISH.getCode();
            for (PaymentTaskEntityExt entityExt : paymentTaskEntityExts) {
                JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
                String status = data.getString(PaymentTaskEnum.STATUS.getAttr());
                if (!Objects.equals(status, finishCode)) {
                    JSONObject updateData = new JSONObject();
                    updateData.put(PaymentTaskEnum.STATUS.getAttr(), finishCode);
                    updateDataEntityList.add(ExplainUtil.getUpdateData(entityExt.getDataId(), updateData, corpid));
                }
            }
            if (updateDataEntityList.size() > 0) {
                paymentTaskModel.batchUpdatePaymentTask(updateDataEntityList, corpid);
            }
        }
    }

    /**
     * 对合同的回款计划进行格式的转化以及一些校验，这边的代码是直接重老的回款计划拷过来，该变量
     *
     * @param formDataSaveDTO
     * @return
     */
    @Override
    public AddBatchDTO beforeSaveBatch(FormDataAddDTO formDataSaveDTO) throws XbbException{
        Map<String, Object> params = BeanUtil.convertBean2Map(formDataSaveDTO, true);
        List<PaasFormExplainEntity> explainList = paasFormExplainModel.list(params);
        if (Objects.isNull(explainList) || explainList.isEmpty()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explainList.get(0).getExplains(), null);
        JSONObject data = formDataSaveDTO.getDataList();
        saasSaveHelp.formatLinkBusiness4SaveByArray(data, PaymentTaskEnum.LINK_CUSTOMER.getAttr(), PaymentTaskEnum.LINK_CUSTOMER_HIDE.getAttr(), PaymentTaskEnum.LINK_CUSTOMER.getFieldType());
        saasSaveHelp.formatLinkBusiness4SaveByArray(data, PaymentTaskEnum.LINK_CONTRACT.getAttr(), PaymentTaskEnum.LINK_CONTRACT_HIDE.getAttr(), PaymentTaskEnum.LINK_CONTRACT.getFieldType());
        Double contractAmount;
        // 来自于合同新建编辑
        Long contractFormId = null;
        Double paymentTaskAmount = 0D;
        Long contractId = null;
        Boolean isNew = false;
        SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = formDataSaveDTO.getSaasNeedRedundantAttrPoJo();
        if (Objects.nonNull(saasNeedRedundantAttrPoJo) && Objects.equals(saasNeedRedundantAttrPoJo.getParentBusinessType(), XbbRefTypeEnum.CONTRACT.getCode())) {
            contractAmount = formDataSaveDTO.getSaasNeedRedundantAttrPoJo().getParentAmount();
            contractFormId = formDataSaveDTO.getSaasNeedRedundantAttrPoJo().getLinkItemFormId();
            isNew = true;
        } else {
            PaasFormDataEntityExt contractEntityExt = contractModel.getByKey(data.getLong(PaymentTaskEnum.LINK_CONTRACT.getAttr()), formDataSaveDTO.getCorpid());
            if (Objects.isNull(contractEntityExt)) {
                throw new XbbException(ContractErrorCodeEnum.API_ERROR_203001);
            }
            contractAmount = contractEntityExt.getData().getDouble(ContractEnum.AMOUNT.getAttr());
            contractFormId = contractEntityExt.getFormId();
            contractId = contractEntityExt.getId();
            isNew = false;
        }


        JSONArray paymentArray = data.getJSONArray(ContractEnum.ADD_PAYMENT.getAttr());
        List<AddMuchFieldPojo> addBatchList = new ArrayList<>();
        List<AddMuchFieldPojo> delBatchList = new ArrayList<>();
        List<AddMuchFieldPojo> updateBatchList = new ArrayList<>();
        List<Object> noChangePaymentList = new ArrayList<>();
        List<ValidateDataDTO> validateDataDTOList = new ArrayList<>();
        List<Long> idIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        FieldAttrEntity serialNoFieldAttr = explainMap.get(PaymentTaskEnum.PAYMENT_TASK_NO.getAttr());
        //下面是移除审批中已经删除的回款计划
        paasFormExplainService.handProcessShouldRemoveValue(formDataSaveDTO.getCorpid(), XbbRefTypeEnum.CONTRACT, XbbRefTypeEnum.PAYMENT_TASK, paymentArray);
        for (Object obj : paymentArray){
            AddMuchFieldPojo addMuchFieldPojo = new AddMuchFieldPojo();
            ValidateDataDTO validateDataDTO = new ValidateDataDTO();
            JSONObject json = (JSONObject) obj;
            Long dataId = json.getLong(StringConstant.DATA_ID);
            addMuchFieldPojo.setId(dataId);
            String serialNo = json.getString(FieldTypeEnum.SERIALNO.getAlias());
            if (Objects.nonNull(serialNoFieldAttr)) {
                if (Objects.equals(serialNoFieldAttr.getStrictController(), BasicConstant.ONE) && StringUtil.isEmpty(serialNo)) {
                    serialNo = saasSaveHelp.getSerialNo(serialNo, formDataSaveDTO, formDataSaveDTO.getCorpid(), serialNoFieldAttr);
                    //json.getJSONObject("data").put(PaymentTaskEnum.PAYMENT_TASK_NO.getAttr(),serialNo);
                }
                addMuchFieldPojo.setSerialNo(serialNo);
            }
            if (serialNo.length() > 50) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208023);
            }
            JSONObject paymentTaskData = json.getJSONObject("data");
            //合同那边批量保存回款计划，需要校验这些回款计划是不是都有执行人
            validateBatchPaymentTask(paymentTaskData,formDataSaveDTO.getCorpid(), data.getString(PaymentTaskEnum.LINK_CONTRACT.getAttr()));
            JSONObject statusJSON = FastJsonHelper.getJsonObjectOrDefaultFromFormData(paymentTaskData, PaymentTaskEnum.STATUS.getAttr(),new JSONObject());
            String status = statusJSON.getString("value");
            /*
            if ( !Objects.equals(status, PaymentTaskStatusEnum.NO_FINISH.getCode()) && Objects.isNull(dataId) && Objects.isNull(formDataSaveDTO.getIsOldProgressData())){
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208039, PaymentErrorCodeEnum.API_ERROR_208039.getMsg());
            }*/
            Integer operationFlag = json.getInteger(StringConstant.OPERATION_FLAG);
            if ( Objects.isNull(dataId) ) {
                operationFlag = null;
            }
            if ( !Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode()) ) {
                saasSaveHelp.validatePayment(paymentTaskData,PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr(),explainMap);
            }
            paymentTaskData.put(PaymentTaskEnum.LINK_CUSTOMER.getAttr(),data.get(PaymentTaskEnum.LINK_CUSTOMER.getAttr()));
            paymentTaskData.put(PaymentTaskEnum.LINK_CUSTOMER_HIDE.getAttr(),data.get(PaymentTaskEnum.LINK_CUSTOMER_HIDE.getAttr()));
            paymentTaskData.put(PaymentTaskEnum.LINK_CONTRACT.getAttr(),data.get(PaymentTaskEnum.LINK_CONTRACT.getAttr()));
            paymentTaskData.put(PaymentTaskEnum.LINK_CONTRACT_HIDE.getAttr(),data.get(PaymentTaskEnum.LINK_CONTRACT_HIDE.getAttr()));
            //把前端传过来的格式转化为要保存到es和数据库中的格式
            saasSaveHelp.formatJsonData(paymentTaskData, PaymentTaskEnum.NOTIFY_TYPE.getAttr(), StringConstant.VALUE);
            saasSaveHelp.formatJsonData(paymentTaskData, PaymentTaskEnum.PAYMENT_TASK_TYPE.getAttr(), StringConstant.VALUE);
            saasSaveHelp.formatJsonData(paymentTaskData, PaymentTaskEnum.STATUS.getAttr(), StringConstant.VALUE);
            Long communicateTime = FastJsonHelper.getLongFromFormData(paymentTaskData, PaymentTaskEnum.EXECUTOR_TIME.getAttr());
            Integer notifyType = FastJsonHelper.getIntegerOrDefaultFromFormData(paymentTaskData, PaymentTaskEnum.NOTIFY_TYPE.getAttr(), PaymentTaskNotifyTypeEnum.NO_NOTIFY.getCode());
            Long notifyTime = FastJsonHelper.getLongFromFormData(paymentTaskData, PaymentTaskEnum.NOTIFY_TIME.getAttr());
            notifyTime = checkCommunicateTime(communicateTime, notifyType, notifyTime, dataId, formDataSaveDTO.getProcessCreatorId());
            if (notifyType.equals(PaymentTaskNotifyTypeEnum.NO_NOTIFY.getCode())) {
                notifyTime = null;
            }
            paymentTaskData.put(PaymentTaskEnum.NOTIFY_TIME.getAttr(), notifyTime);
            //需要移除data里面的owerId和departmentId和serialNo
            paymentTaskData.remove("ownerId");
            paymentTaskData.remove("serialNo");
            addMuchFieldPojo.setData(paymentTaskData);

            BeanUtil.copyProperties(formDataSaveDTO,validateDataDTO);
            validateDataDTO.setData(addMuchFieldPojo.getData());
            validateDataDTO.setSerialNo(serialNo);
            validateDataDTO.setDataId(dataId);
            if (Objects.equals(operationFlag,LinkAddOperationFlagEnum.DEL.getCode())){
                delBatchList.add(addMuchFieldPojo);
                idIn.add(addMuchFieldPojo.getId());
            }else {
                if (Objects.equals(operationFlag,LinkAddOperationFlagEnum.EDIT.getCode())){
                    updateBatchList.add(addMuchFieldPojo);
                    validateDataDTOList.add(validateDataDTO);
                    idIn.add(addMuchFieldPojo.getId());
                }else if (Objects.isNull(dataId)){
                    addBatchList.add(addMuchFieldPojo);
                    validateDataDTOList.add(validateDataDTO);
                } else {
                    noChangePaymentList.add(obj);
                    idIn.add(addMuchFieldPojo.getId());
                }
                //金额计算的时候算回款计划金额的时候只计算未回款计划的
                if (!Objects.equals(PaymentTaskStatusEnum.FINISH.getCode(), status)) {
                    paymentTaskAmount = Arith.add(paymentTaskAmount, FastJsonHelper.getDoubleOrDefaultFromFormData(paymentTaskData, PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr(), 0D));
                }

            }
            validateDataDTO.setExplainMap(explainMap);
            formDataValidateDataHelp.validateData(validateDataDTO);
            ProSaveHelp.analyticalData(validateDataDTO);
            addMuchFieldPojo.setDepartmentId(validateDataDTO.getDepartmentId());
        }

        if (!isNew && contractId != null && contractId != 0L) {
            FormDataUpdateGetDTO formDataUpdateGetDTO = new FormDataUpdateGetDTO();
            BeanUtil.copyProperties(formDataSaveDTO, formDataUpdateGetDTO);
            paymentTaskAmount = Arith.add(paymentTaskAmount,beforeSaveGetTotalAmount(formDataSaveDTO.getCorpid(), contractId, idIn,formDataSaveDTO.getIsTotalPaymentSheetAmount(),formDataUpdateGetDTO));
        }
        if (paymentTaskAmount > contractAmount){
            throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208002);
        }
        if ( paymentTaskAmount < BasicConstant.ZERO_DOUBLE ) {
            throw new XbbException(ImportErrorCodeEnum.API_ERROR_235030);
        }
        // 只有在合同新建时，需要根据合同开关设置去做金额相等校验
        FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(formDataSaveDTO.getCorpid(), contractFormId, FormConfigEnum.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN.getConfig());
        boolean isContractAmountEqualPayment = Objects.equals(FormConfigEnum.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN.getConfigValue(), StringConstant.POSITIVE_NUMBER);
        if ( Objects.nonNull(formConfigEntity) ) {
            if ( Objects.equals(formConfigEntity.getConfigValue(), StringConstant.POSITIVE_NUMBER) ) {
                isContractAmountEqualPayment = true;
            } else {
                isContractAmountEqualPayment = false;
            }
        }
        if ( isContractAmountEqualPayment && (!addBatchList.isEmpty() || !updateBatchList.isEmpty() || !noChangePaymentList.isEmpty()) ) {
            if ( !Objects.equals(paymentTaskAmount, contractAmount) && formDataSaveDTO.getIsTotalPaymentSheetAmount()) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208003);
            }
        }
        AddBatchDTO addBatchDTO = new AddBatchDTO();
        BeanUtil.copyProperties(formDataSaveDTO,addBatchDTO);
        addBatchDTO.setAddBatchList(addBatchList);
        FieldAttrEntity serialField = explainMap.getOrDefault(PaymentTaskEnum.PAYMENT_TASK_NO.getAttr(), new FieldAttrEntity());
        if (Objects.equals(serialField.getNoRepeat(), 1)) {
            Set<String> addSerialNoSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            addBatchList.forEach(addBatch-> addSerialNoSet.add(addBatch.getSerialNo()));
            if (!Objects.equals(addSerialNoSet.size(), addBatchList.size())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.NO_REPEAT, serialField.getAttrName());
            }
        }
        Integer total = addBatchList.size() + updateBatchList.size() - delBatchList.size();
        if (total > StringConstant.MAX_PAYMENT_TASK_COUNT ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.OVER_STEP_MAX_PAYMENT_TASK_COUNT, StringConstant.MAX_PAYMENT_TASK_COUNT);
        }
        addBatchDTO.setAmount(paymentTaskAmount);
        addBatchDTO.setUpdateBatchList(updateBatchList);
        addBatchDTO.setDelBatchList(delBatchList);
        addBatchDTO.setValidateDataDTOList(validateDataDTOList);
        return addBatchDTO;
    }

    /**
     * 校验批量的回款计划
     *
     * @param paymentTaskData
     * @param corpid
     * @param contractId
     */
    private void validateBatchPaymentTask(JSONObject paymentTaskData, String corpid, String contractId) throws XbbException {
        JSONArray checkArray = paymentTaskData.getJSONArray(PaymentTaskEnum.EXECUTOR.getAttr());
        //自定义执行人的具体的值
        JSONArray customArray = paymentTaskData.getJSONArray(PaymentTaskEnum.EXECUTOR_LINKED_TEXT.getAttr());
        boolean checkExecutorTag = false;
        if (Objects.isNull(customArray) || customArray.size() == BasicConstant.ZERO) {
            if (Objects.isNull(checkArray) || checkArray.size() == 0) {
                throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247011);
            }
            List<String> executorTagList = new ArrayList<>();
            for (int m = 0; m < checkArray.size(); m++) {
                Object obj = checkArray.get(m);
                if (obj instanceof String) {
                    executorTagList.add((String)obj);
                }else if (obj instanceof JSONObject) {
                    String value = ((JSONObject) obj).getString("value");
                    executorTagList.add(value);
                }
                /*JSONObject executorJson = checkArray.getJSONObject(m);
                String value = executorJson.getString("value");
                executorTagList.add(value);*/
            }
            if (CollectionUtils.isNotEmpty(executorTagList) && executorTagList.size() == BasicConstant.ONE) {
                if (executorTagList.contains(ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode().toString())) {
                    throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247011);
                }
            }
            if (CollectionsUtil.isEmpty(executorTagList)) {
                checkExecutorTag = true;
            }else if (!executorTagList.contains(ExecutorCheckBoxEnum.MAIN_USER_CHECK.getCode().toString()) && executorTagList.contains(ExecutorCheckBoxEnum.COOPER_USER_CHECK.getCode().toString())) {
                checkExecutorTag = true;
            }
        }
        if (checkExecutorTag) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            param.put("dataId", contractId);
            param.put("corpid", corpid);
            param.put("isMain", BasicConstant.ZERO);
            List<ContractUserEntity> contractUserList = contractUserModel.findEntitys(param);
            if (CollectionUtils.isEmpty(contractUserList)) {
                throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247011);
            }
        }
    }

    /**
     * 回款计划新增
     *
     * @param payMentTaskDTO
     * @return
     * @throws XbbException
     */
    @Override
    public FormDataAddVO pay(PaymentTaskDTO payMentTaskDTO,  SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String loginUserName = payMentTaskDTO.getLoginUserName();
        String corpid = payMentTaskDTO.getCorpid();
        String userId = payMentTaskDTO.getUserId();
        String picUserId = payMentTaskDTO.getUserId();
        Integer businessType = XbbRefTypeEnum.PAYMENT_TASK.getCode();
        List<ReturnUserAndDepartmentPojo> ownerId = saasFormSaveDTO.getOwnerId();
        List<ReturnUserAndDepartmentPojo> coUserId = saasFormSaveDTO.getCoUserId();
        payMentTaskDTO.setOwnerId(ownerId);
        payMentTaskDTO.setCoUserId(coUserId);
        // 审批兼容
        if (payMentTaskDTO.getProcessCreatorId() != null) {
            userId = payMentTaskDTO.getProcessCreatorId();
            UserEntity userEntity = userModel.getByKeyIngoreDel(userId, corpid);
            loginUserName = userEntity.getName();
        }

        FormDataAddVO formDataAddVO = new FormDataAddVO();
        // 批量新增流水号集合
        List<AddMuchFieldPojo> addBatchList = payMentTaskDTO.getAddBatchList();
        List<String> addBatchSerialNoList= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        // 开启严控模式后生成流水号
        PaasFormExplainEntity formExplainEntity = paasFormExplainModel.getByFormId(payMentTaskDTO.getFormId(), payMentTaskDTO.getCorpid());
        if (Objects.isNull(formExplainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(formExplainEntity.getExplains(), null);
        FieldAttrEntity fieldAttrEntity = explainMap.get(PaymentTaskEnum.PAYMENT_TASK_NO.getAttr());
        if (Objects.nonNull(fieldAttrEntity)) {
            String serialNo = "";
            FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
            BeanUtil.copyProperties(payMentTaskDTO, formDataAddDTO);
            for (AddMuchFieldPojo addMuchFieldPojo : addBatchList) {
                if (Objects.equals(fieldAttrEntity.getStrictController(), BasicConstant.ONE) && Objects.isNull(addMuchFieldPojo.getSerialNo())) {
                    serialNo = saasSaveHelp.getSerialNo(serialNo, formDataAddDTO, corpid, fieldAttrEntity);
                    addMuchFieldPojo.setSerialNo(serialNo);
                }
                addBatchSerialNoList.add(addMuchFieldPojo.getSerialNo());
            }
        }
        String addBatchSerialNoStr = StringUtils.join(addBatchSerialNoList, "，");
        // 批量更新流水号集合
        List<AddMuchFieldPojo> updateBatchList = payMentTaskDTO.getUpdateBatchList();
        // 批量删除流水号集合
        List<AddMuchFieldPojo> delBatchList = payMentTaskDTO.getDelBatchList();

        try {
            PaymentTaskInsertBatchVO paymentTaskInsertBatchVO = new PaymentTaskInsertBatchVO();
            PaymentUpdateBatchMuchFieldVO paymentUpdateBatchMuchFieldVO = new PaymentUpdateBatchMuchFieldVO();
            // 删除逻辑
            if (Objects.nonNull(delBatchList) && !delBatchList.isEmpty()) {
                List<Long> idList = new ArrayList<>();
                for (AddMuchFieldPojo item : delBatchList) {
                    idList.add(item.getId());
                }
                PaymentTaskDeleteBatchDTO paymentTaskDeleteBatchDTO = new PaymentTaskDeleteBatchDTO();
                BeanUtil.copyProperties(payMentTaskDTO, paymentTaskDeleteBatchDTO);
                paymentTaskDeleteBatchDTO.setDataIdList(idList);
                PaymentTaskDeleteBatchVO paymentTaskDeleteBatchVO = deleteBatch(paymentTaskDeleteBatchDTO);
                if(Objects.isNull(paymentTaskDeleteBatchVO)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                }else {
                    if(Objects.nonNull(paymentTaskDeleteBatchVO.getErrorTypeList())){
                        StringBuilder errorMsg = new StringBuilder();
                        if(Objects.nonNull(paymentTaskDeleteBatchVO.getErrorDataList())){
                            paymentTaskDeleteBatchVO.getErrorDataList().forEach(msg ->{
                                errorMsg.append(msg+"、");
                            });
                            errorMsg.deleteCharAt(errorMsg.length()-1);
                        }
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,paymentTaskDeleteBatchVO.getErrorDataMemo()+errorMsg.toString());
                    }
                }
            }

            List<AddMuchFieldPojo> addMuchFieldPojoInsertList = new ArrayList<>();
            // 插入数据
            if(Objects.nonNull(addBatchList) && !addBatchList.isEmpty()){
                PaymentTaskInsertBatchDTO paymentTaskInsertBatchDTO = new PaymentTaskInsertBatchDTO();
                BeanUtil.copyProperties(payMentTaskDTO, paymentTaskInsertBatchDTO);
                paymentTaskInsertBatchDTO.setDataList(addBatchList);
                paymentTaskInsertBatchVO = insertBatch(paymentTaskInsertBatchDTO,payMentTaskDTO.getParentNew(), userId, saasFormSaveDTO);

                // 记录日志
                List<PaasFormDataEntityExt> insertList = paymentTaskInsertBatchVO.getInsertList();
                BeanUtil.copyPropertiesList(insertList, addMuchFieldPojoInsertList, AddMuchFieldPojo.class);
                formDataAddVO.setInsertList(insertList);
                if(insertList.size() > 1){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_ADD_FORM_DETAIL), loginUserName, XbbRefTypeEnum.PAYMENT_TASK.getName(), insertList.size());
                    List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    InfoArrPojo infoArrPojo = new InfoArrPojo();
                    infoArrPojo.setTitle(PaymentTaskEnum.PAYMENT_TASK_NO.getAttrName());
                    infoArrPojo.setContent(addBatchSerialNoStr);
                    infoArrPojoList.add(infoArrPojo);
//                    mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.PAYMENT_TASK_PUSH_SET, OperateTypeEnum.NEW, "", "", memo, payMentTaskDTO.getHttpHeader());
                } else if (Objects.equals(insertList.size(), 1)){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_WORK), loginUserName, XbbRefTypeEnum.PAYMENT_TASK.getName(), addBatchSerialNoStr);
//                    mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.PAYMENT_TASK_PUSH_SET, OperateTypeEnum.NEW, insertList.get(0).getId().toString(), addBatchSerialNoStr, memo, payMentTaskDTO.getHttpHeader());
                }
            }
            //更新数据
            if(Objects.nonNull(updateBatchList) && !updateBatchList.isEmpty()){
                PaymentTaskUpdateBatchMuchFieldDTO paymentTaskUpdateBatchMuchFieldDTO = new PaymentTaskUpdateBatchMuchFieldDTO();
                BeanUtil.copyProperties(payMentTaskDTO, paymentTaskUpdateBatchMuchFieldDTO);
                paymentTaskUpdateBatchMuchFieldDTO.setDataList(updateBatchList);
                paymentUpdateBatchMuchFieldVO = updateBatchMuchField(paymentTaskUpdateBatchMuchFieldDTO, true, explainMap);
            }
            //批量新增、编辑、删除图片
            Runnable runnable = () -> {
                try {
                    // 保存回款
                    cabinetFileService.saveBatchCabinetFile(explainMap, addMuchFieldPojoInsertList, updateBatchList, delBatchList,
                            corpid, businessType, picUserId);
                } catch (Exception e) {
                    LOG.error("批量操作图片报错", e);
                }
            };
            threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paymentTaskServiceImpl.pay回款出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
        return formDataAddVO;
    }

    public PaymentTaskInsertBatchVO insertBatch(PaymentTaskInsertBatchDTO paymentTaskInsertBatchDTO, Boolean parentNew, String creatorId, SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaymentTaskInsertBatchVO paymentTaskInsertBatchVO = new PaymentTaskInsertBatchVO();
        try {
            List<PaasFormDataEntityExt> paidForList = new ArrayList<>();
            List<PaasFormDataEntityExt> insertList = new ArrayList<>();
            String corpid = paymentTaskInsertBatchDTO.getCorpid();
            List<PaymentTaskEntityExt> formDataList = new ArrayList<>();
            Long modelType = fundSetService.getModelType(corpid, XbbRefTypeEnum.CRM);
            paymentTaskInsertBatchDTO.getDataList().forEach((item)->{
                PaymentTaskEntityExt paymentTaskEntityExt = new PaymentTaskEntityExt();
                BeanUtil.copyProperties(item, paymentTaskEntityExt);
                paymentTaskEntityExt.setCorpid(corpid);
                paymentTaskEntityExt.setAppId(paymentTaskInsertBatchDTO.getAppId());
                paymentTaskEntityExt.setMenuId(paymentTaskInsertBatchDTO.getMenuId());
                paymentTaskEntityExt.setFormId(paymentTaskInsertBatchDTO.getFormId());
                JSONObject data = item.getData();
                String status = data.getString(PaymentEnum.STATUS.getAttr());
                if(PaymentTaskStatusEnum.FINISH.getCode().equals(status)) {
                    paidForList.add(paymentTaskEntityExt);
                }
                paymentTaskEntityExt.setData(data);
                paymentTaskEntityExt.setCreatorId(creatorId);
                paymentTaskEntityExt.setDepartmentId(1L);
                if (Objects.nonNull(item.getDepartmentId())) {
                    paymentTaskEntityExt.setDepartmentId(item.getDepartmentId());
                }
                if (StringUtil.isNotEmpty(item.getOwnerId())) {
                    paymentTaskEntityExt.setOwnerId(item.getOwnerId());
                } else {
                    paymentTaskEntityExt.setOwnerId(creatorId);
                }
                paymentTaskEntityExt.setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
                long now = DateUtil.getInt();
                paymentTaskEntityExt.setAddTime(now);
                paymentTaskEntityExt.setUpdateTime(now);
                paymentTaskEntityExt.setSysLong10(modelType);
                formDataList.add(paymentTaskEntityExt);
            });
            List<PaymentTaskEntityExt> paymentTaskEntityExtList = paymentTaskModel.insertBatch(formDataList);
            insertList.addAll(paymentTaskEntityExtList);
            paymentTaskInsertBatchVO.setInsertList(insertList);
            paymentTaskInsertBatchVO.setPaidForList(paidForList);

            List<ReturnUserAndDepartmentPojo> ownerId = paymentTaskInsertBatchDTO.getOwnerId() == null ? new ArrayList<>() : paymentTaskInsertBatchDTO.getOwnerId();
            List<ReturnUserAndDepartmentPojo> coUserId = paymentTaskInsertBatchDTO.getCoUserId() == null ? new ArrayList<>() : paymentTaskInsertBatchDTO.getCoUserId();
            // 审批数据和导入数据没传userName,兼容一下
            commonHelp.setUserName4UserPojo(corpid, ownerId, coUserId);
            List<PaymentTaskUserEntity> paymentTaskUserEntityList = handlePaymentTaskUser(paymentTaskEntityExtList, ownerId, coUserId, corpid);
            if (CollectionsUtil.isNotEmpty(paymentTaskUserEntityList)) {
                paymentTaskUserModel.insertBatch(paymentTaskUserEntityList);
            }
            /*
            //手动创建应收，无需和task挂钩
            //判断需不需要批量增加应收款信息 1:“手动创建应收”模式需要添加应收款信息
            if (ModelTypeEnum.PLAN.getCode().equals(modelType)) {
                //新建应收款,这边是从合同那边过来的需要重新赋值一下businessType为回款计划的businessType
                saasFormSaveDTO.setBusinessType(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK.getCode());
                receivablesHelper.createReceivablesHandle(saasFormSaveDTO, modelType, paymentTaskEntityExtList);
            }
             */
            sendPaymentTaskMessage(paymentTaskEntityExtList,saasFormSaveDTO,saasFormSaveDTO.getCorpid());
        } catch (Exception e) {
            LOG.error("paasFormData数据库保存表单数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paymentTaskInsertBatchVO;
    }

    /**
     *批量更新回款计划
     *
     * @param paymentTaskUpdateBatchMuchFieldDTO
     * @param source
     * @return
     * @throws XbbException
     */
    public PaymentUpdateBatchMuchFieldVO updateBatchMuchField(PaymentTaskUpdateBatchMuchFieldDTO paymentTaskUpdateBatchMuchFieldDTO, boolean source, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        PaymentUpdateBatchMuchFieldVO paymentUpdateBatchMuchFieldVO = new PaymentUpdateBatchMuchFieldVO();
        List<AddMuchFieldPojo> dataList = paymentTaskUpdateBatchMuchFieldDTO.getDataList();
        List<String> updateBatchSerialNoList= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        try {
            String corpid = paymentTaskUpdateBatchMuchFieldDTO.getCorpid();
            Map<String, Object> map = BeanUtil.convertBean2Map(paymentTaskUpdateBatchMuchFieldDTO, true);
            List<Long> idList = new ArrayList<>();
            List<PaasFormDataEntityExt> updateList = new ArrayList<>();
            Map<Long,AddMuchFieldPojo> dataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            dataList.forEach(item -> {
                idList.add(item.getId());
                dataMap.put(item.getId(),item);
            });
            map.put("idIn", idList);
            map.put("del", DelEnum.NORMAL.getDel());
            List<PaymentTaskEntityExt> list = paymentTaskModel.findEntitys(map);
            List<Long> esDeleteList = new ArrayList<>();
            if (list == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            } else {
                Set<Long> idSet = new HashSet<>();
                for(PaymentTaskEntityExt paymentTaskEntityExt: list) {
                    updateBatchSerialNoList.add(paymentTaskEntityExt.getSerialNo());
                    JSONObject dbData = paymentTaskEntityExt.getData();
                    AddMuchFieldPojo addMuchFieldPojo = dataMap.getOrDefault(paymentTaskEntityExt.getId(),new AddMuchFieldPojo());
                    for (Map.Entry<String,Object> entry : addMuchFieldPojo.getData().entrySet()){
                            dbData.put(entry.getKey(),entry.getValue());
                    }
                    paymentTaskEntityExt.setData(dbData);
                    paymentTaskEntityExt.setUpdateTime(DateUtil.getNow());
                    updateList.add(paymentTaskEntityExt);
                    idSet.add(paymentTaskEntityExt.getId());
                }
                for(Long id : idList) {
                    if (!idSet.contains(id)) {
                        esDeleteList.add(id);
                    }
                }
            }
            // 删除数据库没有，但是es有的数据
            if (!esDeleteList.isEmpty()) {
                paasEsModel.deleteBatch(esDeleteList, corpid, DelEnum.DELETE.getDel(), IndexTypeEnum.IDX_SAAS_PAYMENT_TASK);
            }
            if (!updateList.isEmpty()) {
                paymentTaskHelp.updateBatch(updateList, corpid, explainMap);
            }

            // 记录日志
            if(source){
                String updateBatchSerialNoStr = StringUtils.join(updateBatchSerialNoList, "，");
                String userId = paymentTaskUpdateBatchMuchFieldDTO.getUserId();
                String loginUserName = paymentTaskUpdateBatchMuchFieldDTO.getLoginUserName();
                if(dataList.size() > 1){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_UPDATE_FORM_DETAIL), loginUserName, XbbRefTypeEnum.PAYMENT_TASK.getName(), dataList.size());
                    List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    InfoArrPojo infoArrPojo = new InfoArrPojo();
                    infoArrPojo.setTitle(PaymentTaskEnum.PAYMENT_TASK_NO.getAttrName());
                    infoArrPojo.setContent(updateBatchSerialNoStr);
                    infoArrPojoList.add(infoArrPojo);
//                    mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.PAYMENT_TASK_PUSH_SET, OperateTypeEnum.EDIT, "", "", memo, paymentTaskUpdateBatchMuchFieldDTO.getHttpHeader());
                } else if (Objects.equals(dataList.size(), 1)){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_WORK), loginUserName, XbbRefTypeEnum.PAYMENT_TASK.getName(), updateBatchSerialNoStr);
//                    mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.PAYMENT_TASK_PUSH_SET, OperateTypeEnum.EDIT, dataList.get(0).getId().toString(), updateBatchSerialNoStr, memo, paymentTaskUpdateBatchMuchFieldDTO.getHttpHeader());
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormData.updateBatchMuchField数据库批量更新出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paymentUpdateBatchMuchFieldVO;
    }

    /**
     * 返回回款计划执行者列表信息
     *
     * @param paymentTaskEntityExtList
     * @param ownerId
     * @param coUserId
     * @param corpid
     * @return
     */
    private List<PaymentTaskUserEntity> handlePaymentTaskUser(List<PaymentTaskEntityExt> paymentTaskEntityExtList, List<ReturnUserAndDepartmentPojo> ownerId, List<ReturnUserAndDepartmentPojo> coUserId, String corpid) {
        List<PaymentTaskUserEntity> paymentTaskUserEntities = new ArrayList<>();
        for (PaymentTaskEntityExt paymentTaskEntityExt : paymentTaskEntityExtList) {
            List<String> pushUserList = new ArrayList<>();
            JSONObject jsonObject = paymentTaskEntityExt.getData();
            List<String> executorLinkedList = (List<String>) jsonObject.get(PaymentTaskEnum.EXECUTOR.getAttr());
            for (String executorLinked : executorLinkedList) {
                if (PaymentTaskConstant.OWER_NUM.equals(executorLinked)) {
                    for (ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo : ownerId) {
                        pushUserList.add((String)returnUserAndDepartmentPojo.getId());
                    }
                }else if (PaymentTaskConstant.CO_OWER_NUM.equals(executorLinked)) {
                    for (ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo : coUserId) {
                        pushUserList.add((String)returnUserAndDepartmentPojo.getId());
                    }
                }
            }
            //查询出所有的用户信息,还需要加上自定义执行人的信息
            Object object = jsonObject.get(PaymentTaskEnum.EXECUTOR_LINKED_TEXT.getAttr());
            if (!Objects.isNull(object)) {
                List<String> defineUser = (List<String>) object;
                pushUserList.addAll(defineUser);
            }
            List<String> disList = pushUserList.stream().distinct().collect(Collectors.toList());
            Map<String, Object> userParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            userParam.put("del", BasicConstant.ZERO);
            userParam.put("corpid", corpid);
            userParam.put("userIdIn", disList);
            List<UserEntity> users = userModel.findEntitys(userParam);
            for (UserEntity userEntity : users) {
                PaymentTaskUserEntity paymentTaskUserEntity = new PaymentTaskUserEntity();
                paymentTaskUserEntity.setUserId(userEntity.getUserId());
                paymentTaskUserEntity.setCorpid(corpid);
                paymentTaskUserEntity.setDataId(paymentTaskEntityExt.getId());
                paymentTaskUserEntity.setUserName(userEntity.getName());
                paymentTaskUserEntity.setUserAvatar(userEntity.getAvatar());
                paymentTaskUserEntity.setDel(BasicConstant.ZERO);
                paymentTaskUserEntity.setAddTime(paymentTaskEntityExt.getAddTime());
                paymentTaskUserEntity.setUpdateTime(paymentTaskEntityExt.getUpdateTime());
                paymentTaskUserEntities.add(paymentTaskUserEntity);
            }
            paymentTaskEntityExt.setPushUserlist(disList);
        }

        return paymentTaskUserEntities;
    }


    /**
     *　合同"未收金额"
     *　回款计划的"计划收款金额"
     *　合同金额-已生成的应收金额
     * @param corpid
     * @param contractId
     * @param idIn
     * @param isTotalPaymentSheet
     * @param formDataUpdateGetDTO
     * @return
     * @throws XbbException
     */
    public Double beforeSaveGetTotalAmount(String corpid, Long contractId, List<Long> idIn, Boolean isTotalPaymentSheet,FormDataUpdateGetDTO formDataUpdateGetDTO) throws XbbException {
        Double paymentTaskAmount = 0D;
        List<AggSumDTO> sumList = new ArrayList<>();
        AggSumDTO aggSumDTO = new AggSumDTO();
        aggSumDTO.setAttr(PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr());
        aggSumDTO.setField(PaymentTaskEnum.getAttrConnectData(PaymentTaskEnum.PAYMENT_TASK_NUM));
        sumList.add(aggSumDTO);
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery(ParameterConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
        boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(PaymentTaskEnum.getEsAttr4Keyword(PaymentTaskEnum.LINK_CONTRACT), contractId));
        if ( !idIn.isEmpty() ) {
            boolQueryBuilder.filter(boolQuery().mustNot(termsQuery(BasicConstant.DATAID, idIn)));
        }
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYMENT_TASK;

        List<AggSumVO> aggSumList = esHelper.aggSumByField(indexTypeEnum.getIndex(), indexTypeEnum.getType(), sumList, searchQuery);
        for ( AggSumVO aggSumVO : aggSumList ) {
            if (PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr().equals(aggSumVO.getAttr()) ) {
                Double amount = aggSumVO.getValue() == null ? 0D : Double.parseDouble(aggSumVO.getValue().toString());
                paymentTaskAmount = Arith.add(paymentTaskAmount, amount);
            }
        }
        return paymentTaskAmount;
    }

    /**
     * 完成对金额的封装
     *
     * @param data
     * @return
     */
    private JSONObject handleMoney(JSONObject data) throws XbbException {
        JSONObject others = new JSONObject();
        double paymentTaskMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(data, PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr(), 0D);
        others.put("contractMoney", paymentTaskMoney);
        return others;
    }

    /**
     * 获取查询的员工
     *
     * @param paymentTaskGetDTO 参数
     * @return 员工idList
     * @throws XbbException
     */
    private List<String> getUserIdList(PaymentTaskGetDTO paymentTaskGetDTO) throws XbbException {
        String userId = paymentTaskGetDTO.getUserId();
        String corpid = paymentTaskGetDTO.getCorpid();
        UserEntity userEntity = userModel.getByKey(userId, corpid);
        //可见的userId
        List<String> seenUserId = new ArrayList<>();
        //分组
        Integer listGroupId = paymentTaskGetDTO.getListGroupId();
        listGroupId = listGroupId == null ? 0 : listGroupId;
        switch (listGroupId) {
            case 0:
                //全部,不可以看到离职
                Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.PAYMENT_TASK.getCode(), null);
                seenUserId = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ZERO, false);
                break;
            case 21:
                //我的
                seenUserId.add(userId);
                break;
            case 22:
                //下属,不可以看到离职
                Integer permission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.PAYMENT_TASK.getCode(), null);
                seenUserId = userModel.getSubIdListByDataPermission(permission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ZERO, true);
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        //选择的userId
        List<String> checkUserIdIn = new ArrayList<>();
        if (Objects.equals(paymentTaskGetDTO.getTreeType(), TREE_TYPE_STAFF)) {
            checkUserIdIn.add(paymentTaskGetDTO.getPid());
            seenUserId.retainAll(checkUserIdIn);
        } else if (Objects.equals(paymentTaskGetDTO.getTreeType(), TREE_TYPE_DEPARTMENT) && !Objects.equals(paymentTaskGetDTO.getPid(), "1")) {
            //如果是部门的情况下，要排除全公司的情况
            Long depId = StringUtil.StringToLong(paymentTaskGetDTO.getPid());
            checkUserIdIn = userModel.getUserIdsRecursionDep(Collections.singletonList(depId), corpid);
            seenUserId.retainAll(checkUserIdIn);
        } else {

        }
        if (seenUserId.isEmpty()) {
            seenUserId.add("-1");
        }
        return seenUserId;
    }

    /**
     * 设置范围筛选
     *
     * @param paymentTaskGetDTO
     * @param conditionsEntityExtList
     * @throws
     * @author long.rao
     * @date 2020-03-03 10:49
     */
    private void rangeScreen(PaymentTaskGetDTO paymentTaskGetDTO, List<ConditionsEntityExt> conditionsEntityExtList) throws XbbException {
        if (Objects.equals(paymentTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
            return;
        }
        JSONObject rangeScreen = paymentTaskGetDTO.getRangeScreen();
        if (Objects.isNull(rangeScreen) || Objects.isNull(rangeScreen.get(RangeScreenConstant.TYPE)) || StringUtil.isEmpty(rangeScreen.getString(RangeScreenConstant.TYPE)) || Objects.isNull(rangeScreen.get(RangeScreenConstant.VALUE))) {
            return;
        }
        String type;
        List<String> values;
        try {
            type = rangeScreen.getString(RangeScreenConstant.TYPE);
            values = rangeScreen.getJSONArray(RangeScreenConstant.VALUE).toJavaList(String.class);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), "PaymentTaskServiceImpl.rangeScreen中的commonFilter参数错误");
        }
        if (CollectionsUtil.isEmpty(values)) {
            return;
        }
        if (Objects.equals(type, RangeScreenConstant.DEPARTMENT)) {
            List<Long> deptIds = new ArrayList<>(values.size());
            values.forEach(item -> deptIds.add(Long.valueOf(item)));
            values = userModel.getUserIdsRecursionDep(deptIds, paymentTaskGetDTO.getCorpid(), 1, true);
        }
        ConditionsEntityExt teamConditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.TEAM_USER.getAlias(), null, FieldTypeEnum.TEAM_USER.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(values));
        conditionsEntityExtList.add(teamConditionsEntityExt);
    }


    /**
     * 执行人校验
     *
     * @param data
     * @param contractId
     * @param corpid
     * @throws
     * @author long.rao
     * @date 2019-02-20 21:51
     */
    private void validateExeCutor(JSONObject data, Long contractId, String corpid) throws XbbException {
        try {
            boolean isManager = false;
            boolean isCooper = false;
            boolean isCustom = false;
            JSONArray checkArray = data.getJSONArray(PaymentTaskEnum.EXECUTOR.getAttr());
            for (Object obj : checkArray) {
                Integer check = Integer.parseInt(obj.toString());
                if (Objects.equals(check, ExecutorCheckBoxEnum.MAIN_USER_CHECK.getCode())) {
                    isManager = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.COOPER_USER_CHECK.getCode())) {
                    isCooper = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode())) {
                    isCustom = true;
                }
            }
            //执行人员
            List<String> thisUserIds = new ArrayList<>();
            //查找所有合同的协同团队
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            param.put("dataId", contractId);
            param.put("corpid", corpid);
            if (isManager) {
                param.put("isMain", BasicConstant.ONE);
                List<ContractUserEntity> contractUserList = contractUserModel.findEntitys(param);
                for (ContractUserEntity contractUserEntity : contractUserList) {
                    thisUserIds.add(contractUserEntity.getUserId());
                }
            }
            if (isCooper) {
                param.put("isMain", BasicConstant.ZERO);
                List<ContractUserEntity> corContractUserList = contractUserModel.findEntitys(param);
                for (ContractUserEntity contractUserEntity : corContractUserList) {
                    thisUserIds.add(contractUserEntity.getUserId());
                }
            }
            JSONArray userArray = data.getJSONArray(PaymentTaskEnum.EXECUTOR_LINKED_TEXT.getAttr());
            if (isCustom && userArray != null) {
                for (Object userObj : userArray) {
                    String customUserId = userObj.toString();
                    thisUserIds.add(customUserId);
                }
            }
            if (CollectionsUtil.isEmpty(thisUserIds)) {
                throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247011);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }

    /**
     * 校验执行时间和提醒时间
     *
     * @param communicateTime 执行时间
     * @param remindType      提醒类型
     * @param notifyTime      提醒时间
     * @param processCreatorId  审批的创建人id，审批中的数据不判断
     * @throws XbbException
     * @author long.rao
     * @date 2019-02-16 22:24
     */
    private Long checkCommunicateTime(Long communicateTime, Integer remindType, Long notifyTime, Long dataId, String processCreatorId) throws XbbException {
        long now = DateUtil.getInt();
        if (communicateTime == null || communicateTime == 0) {
            throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247002);
        } else if (dataId == null && communicateTime < now && StringUtil.isEmpty(processCreatorId)) {
            //合同审批带回款计划不走下面的判断
            throw new XbbException(PayPlanErrorCodeEnum.API_ERROR_247001);
        }
        if (remindType == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
        }
        CommunicatePlanNotifyTypeEnum communicatePlanNotifyTypeEnum = CommunicatePlanNotifyTypeEnum.getByCode(remindType);
        switch (communicatePlanNotifyTypeEnum) {
            case NO_NOTIFY:
                notifyTime = communicateTime;
                break;
            case ADVANCE_ONE_QUARTER_HOUR:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_MINUTE * 15;
                break;
            case ADVANCE_ONE_HOUR:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_HOUR;
                break;
            case ADVANCE_ONE_DAY:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_DAY;
                break;
            case ADVANCE_THREE_DAY:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_DAY * 3;
                break;
            case ADVANCE_ONE_WEEK:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_WEEK;
                break;
            case CUSTOM_TIME:
                if (notifyTime == null) {
                    notifyTime = communicateTime;
                }
                break;
            default:
                break;
        }
        if (notifyTime == null) {
            notifyTime = communicateTime;
        }
        if (!communicatePlanNotifyTypeEnum.equals(CommunicatePlanNotifyTypeEnum.CUSTOM_TIME) && notifyTime > communicateTime) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214004);
        }else if (dataId == null && communicatePlanNotifyTypeEnum.equals(CommunicatePlanNotifyTypeEnum.CUSTOM_TIME) && notifyTime < now) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214004);
        }
        return notifyTime;
    }
}
